Pregunta

En Python, ¿cómo puedo analizar una cadena alfanumérica como "545.2222" a su correspondiente valor de tipo float, 545.2222?O analizar la cadena "31" para un entero, 31?

Sólo quiero saber cómo analizar un flotador str a un float, y (por separado) un int str a un int.

¿Fue útil?

Solución

>>> a = "545.2222"
>>> float(a)
545.22220000000004
>>> int(float(a))
545

Otros consejos

def num(s):
    try:
        return int(s)
    except ValueError:
        return float(s)

Python método para comprobar si una cadena es un flotador:

def is_float(value):
  try:
    float(value)
    return True
  except:
    return False

Un nombre más largo y más preciso para esta función podría ser: is_convertible_to_float(value)

¿Qué es, y no es un flotador en Python que puede sorprender:

val                   is_float(val) Note
--------------------  ----------   --------------------------------
""                    False        Blank string
"127"                 True         Passed string
True                  True         Pure sweet Truth
"True"                False        Vile contemptible lie
False                 True         So false it becomes true
"123.456"             True         Decimal
"      -127    "      True         Spaces trimmed
"\t\n12\r\n"          True         whitespace ignored
"NaN"                 True         Not a number
"NaNanananaBATMAN"    False        I am Batman
"-iNF"                True         Negative infinity
"123.E4"              True         Exponential notation
".1"                  True         mantissa only
"1,234"               False        Commas gtfo
u'\x30'               True         Unicode is fine.
"NULL"                False        Null is not special
0x3fade               True         Hexadecimal
"6e7777777777777"     True         Shrunk to infinity
"1.797693e+308"       True         This is max value
"infinity"            True         Same as inf
"infinityandBEYOND"   False        Extra characters wreck it
"12.34.56"            False        Only one dot allowed
u'四'                 False        Japanese '4' is not a float.
"#56"                 False        Pound sign
"56%"                 False        Percent of what?
"0E0"                 True         Exponential, move dot 0 places
0**0                  True         0___0  Exponentiation
"-5e-5"               True         Raise to a negative number
"+1e1"                True         Plus is OK with exponent
"+1e1^5"              False        Fancy exponent not interpreted
"+1e1.3"              False        No decimals in exponent
"-+1"                 False        Make up your mind
"(1)"                 False        Parenthesis is bad

Se cree que sabe lo que son los números? Usted no es tan bueno como usted piensa! No es una gran sorpresa.

No utilizar este código en el software críticos para la vida!

La captura de amplias excepciones de esta manera, matando a los canarios y tragándose la excepción crea una pequeña posibilidad de que un flotador válida como cadena volverá falsa. La línea de código puede float(...) fallado por alguna de las mil razones que no tienen nada que ver con el contenido de la cadena. Pero si usted está escribiendo el software críticos para la vida en un idioma prototipo de pato a escribir como Python, entonces usted tiene problemas mucho más grandes.

Este es otro método que merece ser mencionado aquí, ast.literal_eval :

  

Esto puede ser usado para evaluar de forma segura cadenas que contengan expresiones Python de fuentes no fiables sin la necesidad de analizar los valores de uno mismo.

Es decir, un 'eval' segura

>>> import ast
>>> ast.literal_eval("545.2222")
545.2222
>>> ast.literal_eval("31")
31
float(x) if '.' in x else int(x)

Localización y comas

Debe tener en cuenta la posibilidad de comas en la representación de cadena de un número, por casos como float("545,545.2222") la que se produce una excepción. En su lugar, utilizar métodos en locale para convertir las cadenas en números e interpretar correctamente las comas. El método locale.atof convierte a un flotador en un solo paso una vez que la configuración regional se ha establecido para la convención número deseado.

Ejemplo 1 - Estados Unidos número convenciones

En los Estados Unidos y el Reino Unido, las comas se pueden utilizar como un separador de miles. En este ejemplo, con la configuración regional de América, la coma se maneja adecuadamente como separador:

>>> import locale
>>> a = u'545,545.2222'
>>> locale.setlocale(locale.LC_ALL, 'en_US.UTF-8')
'en_US.UTF-8'
>>> locale.atof(a)
545545.2222
>>> int(locale.atof(a))
545545
>>>

Ejemplo 2 - European convenciones de numeración

En el mayoría de los países del mundo , comas se utilizan para las marcas decimales en lugar de períodos. En este ejemplo con el entorno local francés, la coma se maneja correctamente como una marca decimal:

>>> import locale
>>> b = u'545,2222'
>>> locale.setlocale(locale.LC_ALL, 'fr_FR')
'fr_FR'
>>> locale.atof(b)
545.2222

El locale.atoi método también está disponible, pero el argumento debe ser un entero.

Si no es contrario a los módulos de terceros, se puede consultar la fastnumbers módulo. Se proporciona una función llamada fast_real que hace exactamente lo que esta pregunta es pidiendo y lo hace más rápido que una implementación de Python puro:

>>> from fastnumbers import fast_real
>>> fast_real("545.2222")
545.2222
>>> type(fast_real("545.2222"))
float
>>> fast_real("31")
31
>>> type(fast_real("31"))
int

Usuarios codelogic y Harley son correctas, pero tenga en cuenta si conoce la cadena es un número entero (por ejemplo, 545) puede llamar a int ( "545" ) sin primero fundición a flotar.

Si las cuerdas están en una lista, puede utilizar la función de mapa así.

>>> x = ["545.0", "545.6", "999.2"]
>>> map(float, x)
[545.0, 545.60000000000002, 999.20000000000005]
>>>

Es sólo es bueno si son todos del mismo tipo.

La pregunta parece un poco viejo. Pero permítanme sugerir una función, parseStr, lo que hace algo similar, es decir, vuelve entero o flotar y si una cadena ASCII dado no se puede convertir en ninguno de ellos se lo devuelve intacto. El código, por supuesto, podría ser ajustado para hacer lo que desee:

   >>> import string
   >>> parseStr = lambda x: x.isalpha() and x or x.isdigit() and \
   ...                      int(x) or x.isalnum() and x or \
   ...                      len(set(string.punctuation).intersection(x)) == 1 and \
   ...                      x.count('.') == 1 and float(x) or x
   >>> parseStr('123')
   123
   >>> parseStr('123.3')
   123.3
   >>> parseStr('3HC1')
   '3HC1'
   >>> parseStr('12.e5')
   1200000.0
   >>> parseStr('12$5')
   '12$5'
   >>> parseStr('12.2.2')
   '12.2.2'

En Python, ¿cómo puedo analizar una cadena alfanumérica como "545.2222" a su correspondiente valor de tipo float, 542.2222?O analizar la cadena "31" a un entero, 31? Sólo quiero saber cómo analizar un float string a un flotador, y (por separado) int string int.

Es bueno que pedir por separado.Si estás mezcla de ellos, puede ser el establecimiento de sí mismo para problemas más adelante.La respuesta simple es:

"545.2222" flotar:

>>> float("545.2222")
545.2222

"31" para un entero:

>>> int("31")
31

Otras conversiones, enteros y de las cadenas y los literales:

Las conversiones a partir de distintas bases, y usted debe saber la base de anticipación (10 es el valor predeterminado).Nota puede prefijo de ellos con lo de Python espera para su literales (ver más abajo) o quitar el prefijo:

>>> int("0b11111", 2)
31
>>> int("11111", 2)
31
>>> int('0o37', 8)
31
>>> int('37', 8)
31
>>> int('0x1f', 16)
31
>>> int('1f', 16)
31

Si usted no sabe la base de anticipación, pero usted sabe que va a tener el prefijo correcto, Python puede inferir esto para usted si usted pase 0 como la base:

>>> int("0b11111", 0)
31
>>> int('0o37', 0)
31
>>> int('0x1f', 0)
31

No Decimales (es decir,Entero) Literales de otras Bases

Si tu motivación es tener su propio código de representar claramente codificado valores específicos, sin embargo, puede que no necesite para convertir desde las bases - usted puede dejar de Python hacer automáticamente con la sintaxis correcta.

Usted puede utilizar el propósito de prefijos para obtener una conversión automática a números enteros con los siguientes literales.Estos son válidas para Python 2 y 3:

El binario, el prefijo 0b

>>> 0b11111
31

Octal, prefijo 0o

>>> 0o37
31

Hexadecimal, prefijo 0x

>>> 0x1f
31

Esto puede ser útil cuando se describe el binario banderas, los permisos de archivo en el código, o valores hexadecimales de los colores - por ejemplo, la nota de sin comillas:

>>> 0b10101 # binary flags
21
>>> 0o755 # read, write, execute perms for owner, read & ex for group & others
493
>>> 0xffffff # the color, white, max values for red, green, and blue
16777215

Hacer ambigua Python 2 octals compatible con Python 3

Si usted ve un número entero que comienza con un 0, en Python 2, esto es (en desuso) octal sintaxis.

>>> 037
31

Es malo porque se ve como el valor debe ser 37.Así que en Python 3, ahora se plantea una SyntaxError:

>>> 037
  File "<stdin>", line 1
    037
      ^
SyntaxError: invalid token

Convertir tu Python 2 octals a octals que trabajar en 2 y 3 con la 0o prefijo:

>>> 0o37
31

float("545.2222") y int(float("545.2222"))

El analizador YAML puede ayudar a determinar qué tipo de datos es la cadena. Utilice yaml.load(), y luego se puede utilizar para probar type(result) para el tipo:

>>> import yaml

>>> a = "545.2222"
>>> result = yaml.load(a)
>>> result
545.22220000000004
>>> type(result)
<type 'float'>

>>> b = "31"
>>> result = yaml.load(b)
>>> result
31
>>> type(result)
<type 'int'>

>>> c = "HI"
>>> result = yaml.load(c)
>>> result
'HI'
>>> type(result)
<type 'str'>

Yo uso esta función para la que

import ast

def parse_str(s):
   try:
      return ast.literal_eval(str(s))
   except:
      return

Será convertir la cadena en su tipo

value = parse_str('1')  # Returns Integer
value = parse_str('1.5')  # Returns Float
def get_int_or_float(v):
    number_as_float = float(v)
    number_as_int = int(number_as_float)
    return number_as_int if number_as_float == number_as_int else number_as_float
def num(s):
    """num(s)
    num(3),num(3.7)-->3
    num('3')-->3, num('3.7')-->3.7
    num('3,700')-->ValueError
    num('3a'),num('a3'),-->ValueError
    num('3e4') --> 30000.0
    """
    try:
        return int(s)
    except ValueError:
        try:
            return float(s)
        except ValueError:
            raise ValueError('argument is not a string of number')

Es necesario tomar en cuenta el redondeo para hacer esto correctamente.

es decir. int (5,1) => 5      int (5,6) => 5 - mal, debe ser de 6 por lo que hacemos int (5,6 + 0,5) => 6

def convert(n):
    try:
        return int(n)
    except ValueError:
        return float(n + 0.5)

Me sorprende que nadie ha mencionado expresiones regulares porque a veces cadena debe ser preparado y se normalizó antes de emitir el número

import re
def parseNumber(value, as_int=False):
    try:
        number = float(re.sub('[^.\-\d]', '', value))
        if as_int:
            return int(number + 0.5)
        else:
            return number
    except ValueError:
        return float('nan')  # or None if you wish

uso:

parseNumber('13,345')
> 13345.0

parseNumber('- 123 000')
> -123000.0

parseNumber('99999\n')
> 99999.0

Y, por cierto, algo que compruebe que tiene un número:

import numbers
def is_number(value):
    return isinstance(value, numbers.Number)
    # will work with int, float, long, Decimal

Para encasillado en Python utilizar las funtions de constructor de la clase, pasando la cadena (o cualquier valor que está tratando de fundido) como parámetro.

Por ejemplo:

>>>float("23.333")
   23.333

Entre bastidores, pitón está llamando a los objetos __float__ método, que debe devolver una representación de flotación del parámetro. Esto es especialmente potente, como se puede definir sus propios tipos (el uso de clases) con un método __float__ de modo que se puede lanzar en un flotador usando flotador (myObject).

Esta es una versión corregida de https://stackoverflow.com/a/33017514/5973334

Esto va a tratar de analizar una cadena y regresar ya sea int o float dependiendo de lo que la cadena representa. Podría elevarse excepciones de análisis o tienen un comportamiento inesperado .

  def get_int_or_float(v):
        number_as_float = float(v)
        number_as_int = int(number_as_float)
        return number_as_int if number_as_float == number_as_int else 
        number_as_float

Uso:

def num(s):
    try:
        for each in s:
            yield int(each)
    except ValueError:
        yield float(each)
a = num(["123.55","345","44"])
print a.next()
print a.next()

Esta es la forma más Pythonic que podía ocurrir.

Uso:

>>> str_float = "545.2222"
>>> float(str_float)
545.2222
>>> type(_) # Check its type
<type 'float'>

>>> str_int = "31"
>>> int(str_int)
31
>>> type(_) # Check its type
<type 'int'>

Esta es una función que convertirá cualquier object (no sólo str) a int o float, sobre la base de si la cadena real proporcionada ve como int o float. Además si se trata de un objeto que tiene ambos métodos __float y __int__, el valor predeterminado es el uso de __float__

def conv_to_num(x, num_type='asis'):
    '''Converts an object to a number if possible.
    num_type: int, float, 'asis'
    Defaults to floating point in case of ambiguity.
    '''
    import numbers

    is_num, is_str, is_other = [False]*3

    if isinstance(x, numbers.Number):
        is_num = True
    elif isinstance(x, str):
        is_str = True

    is_other = not any([is_num, is_str])

    if is_num:
        res = x
    elif is_str:
        is_float, is_int, is_char = [False]*3
        try:
            res = float(x)
            if '.' in x:
                is_float = True
            else:
                is_int = True
        except ValueError:
            res = x
            is_char = True

    else:
        if num_type == 'asis':
            funcs = [int, float]
        else:
            funcs = [num_type]

        for func in funcs:
            try:
                res = func(x)
                break
            except TypeError:
                continue
        else:
            res = x

Aquí hay otra interpretación de su pregunta (pista: es vaga). Es posible que estés buscando algo como esto:

def parseIntOrFloat( aString ):
    return eval( aString )

Funciona de la siguiente ...

>>> parseIntOrFloat("545.2222")
545.22220000000004
>>> parseIntOrFloat("545")
545

En teoría, hay una vulnerabilidad de inyección. La cadena puede ser, por ejemplo "import os; os.abort()". Sin ningún tipo de fondo en donde la cadena viene, sin embargo, la posibilidad es la especulación teórica. Dado que la cuestión es vago, no es del todo claro si esta vulnerabilidad existe realmente o no.

Licenciado bajo: CC-BY-SA con atribución
No afiliado a StackOverflow
scroll top