variable tipos tipo texto numeros numero letras imprimir flotantes decimales datos convertir python rational-numbers

tipos - ¿Cómo convertir cadenas de números racionales y decimales a flotantes en python?



variable tipo texto en python (10)

Analizaría la cadena si la conversión falla:

>>> def convert(s): try: return float(s) except ValueError: num, denom = s.split(''/'') return float(num) / float(denom) ... >>> convert("0.1234") 0.1234 >>> convert("1/2") 0.5

En general, usar eval es una mala idea, ya que es un riesgo para la seguridad. Especialmente si la cadena que se evalúa proviene de fuera del sistema.

¿Cómo puedo convertir cadenas que denotan números decimales o racionales en flotadores?

>>> ["0.1234", "1/2"] [''0.1234'', ''1/2'']

Me gustaría [0.1234, 0.5].

eval es lo que estaba pensando pero sin suerte:

>>> eval("1/2") 0


Como han señalado otros, el uso de eval es potencialmente un riesgo para la seguridad y, sin duda, un mal hábito de penetración. (Si no cree que sea tan arriesgado como el exec , imagine __import__(''os'').system(''rm -rf /'') algo como: __import__(''os'').system(''rm -rf /'') )

Sin embargo, si tiene Python 2.6 o superior, puede usar ast.literal_eval , para lo cual la cadena proporcionada:

solo puede consistir en las siguientes estructuras literales de Python: cadenas, números, tuplas, listas, dictados, booleanos y Ninguno.

Por lo tanto, debería ser bastante seguro :-)


El operador / hace una división entera. Tratar:

>>> eval("1.0*" + "1/2") 0.5

Como eval() es potencialmente peligroso, siempre debes verificar con precisión lo que le estás pasando:

>>> import re >>> s = "1/2" >>> if re.match(r"/d+//d+$", s): ... eval("1.0*" + s) ... 0.5

Sin embargo, si se toma la molestia de hacer coincidir la entrada con una expresión regular en primer lugar, también podría usar r"(/d+)/(/d+)$" para extraer el numerador y el denominador, haga la división usted mismo, y evite por completo eval() :

>>> m = re.match(r"(/d+)/(/d+)$", s) >>> if m: ... float(m.group(1)) / float(m.group(2)) ... 0.5


El problema con eval es que, como en python, el cociente de enteros es un entero. Entonces, tienes varias opciones.

El primero es simplemente hacer flotantes de retorno de división de enteros:

from __future__ import division

El otro es dividir el número racional:

reduce(lambda x, y: x*y, map(int, rat_str.split("/")), 1)

Donde rat_str es la cadena con un número racional.


Esto se debe a que Python interpreta 1 y 2 como enteros y no como flotantes. Necesita ser 1.0 / 2.0 o alguna combinación de eso.


Las sugerencias con la from __future__ import division combinada con eval ciertamente funcionarán.

Probablemente valga la pena señalar que las sugerencias que no usan eval sino que analizan la cadena lo hacen porque eval es peligroso: si hay alguna forma de enviar una cadena arbitraria a eval , entonces su sistema es vulnerable. Entonces es un mal hábito. (Pero si esto es solo un código rápido y sucio, ¡probablemente no sea tan importante!)


Otra opción (también solo para 2.6 y superior) es el módulo de fractions .

>>> from fractions import Fraction >>> Fraction("0.1234") Fraction(617, 5000) >>> Fraction("1/2") Fraction(1, 2) >>> float(Fraction("0.1234")) 0.1234 >>> float(Fraction("1/2")) 0.5


Use from __future__ import division para obtener el comportamiento que desea. Luego, en un apuro, puedes hacer algo como

from __future__ import division strings = ["0.1234", "1/2", "2/3"] numbers = map(eval, strings)

para obtener una lista de flotadores de sus cadenas. Si quiere hacer esto de la manera "correcta", no use eval() , sino que escriba una función que acepte una cadena y llame a float() si no contiene ninguna barra, o analiza la cadena y divide el numerador y denominador si hay una barra en él.

Una forma de hacerlo:

def parse_float_string(x) parts = x.split(''/'', 1) if len(parts) == 1: return float(x) elif len(parts) == 2: return float(parts[0])/float(parts[1]) else: raise ValueError

Entonces solo el map(parse_float_string, strings) te dará tu lista.


En Python 3, esto debería funcionar.

>>> x = ["0.1234", "1/2"] >>> [eval(i) for i in x] [0.1234, 0.5]


sympy puede ayudarte aquí:

import sympy half = sympy.Rational(''1/2'') p1234 = sympy.Rational(''0.1234'') print ''%f, %f" % (half, p1234)