txt texto parser parsear parse generador framework create python parsing

texto - python parser framework



¿Convertir fracción a flotar? (9)

Aunque deberías alejarte completamente de la evaluación. Quizás alguna versión más refinada de:

num,den = s.split( ''/'' ) wh, num = num.split() result = wh + (float(num)/float(den))

Lo sentimos, destinado a ser num.split no s.split y cast. Editado

Algo así como esta pregunta , pero a la inversa.

Dada una cadena como 1 , 1/2 o 1 2/3 , ¿cuál es la mejor manera de convertirlo en un flotador? Estoy pensando en usar expresiones regulares caso por caso, pero tal vez alguien sepa de una manera mejor, o una solución preexistente. Esperaba poder usar eval , pero creo que el tercer caso lo impide.


Dependiendo de la sintaxis que desee admitir para sus fracciones, eval(''+''.join(s.split())) (con la división verdadera en su lugar, es decir, Python 3 o from __future__ import division en Python 2 - trabajo. Cubría todos los casos que mencionas, en particular.


Esa podría ser una solución sucia, pero podría convertir espacios en un signo + para resolver el tercer caso (o para - si su fracción es negativa).


Esta implementación evita el uso de eval y funciona en versiones anteriores a 2.6 de Python.

# matches a string consting of an integer followed by either a divisor # ("/" and an integer) or some spaces and a simple fraction (two integers # separated by "/") FRACTION_REGEX = re.compile(r''^(/d+)(?:(?:/s+(/d+))?/(/d+))?$'') def parse(x): i, n, d = FRACTION_REGEX.match(x).groups() if d is None: n, d = 0, 1 # if d is None, then n is also None if n is None: i, n = 0, i return float(i) + float(n) / float(d)

Probar:

>>> for x in [''1'', ''1/2'', ''1 2/3'']: print(repr(parse(x))) ... 1.0 0.5 1.6666666666666665


Veo que ya hay varias respuestas buenas aquí, pero he tenido buena suerte con esto. También tiene el beneficio de que tolerará cadenas sin fracción si está analizando conjuntos mixtos de datos, por lo que no es necesario verificar si se trata de una cadena de fracción o no por adelantado.

def convert_to_float(frac_str): try: return float(frac_str) except ValueError: try: num, denom = frac_str.split(''/'') except ValueError: return None try: leading, num = num.split('' '') except ValueError: return float(num) / float(denom) if float(leading) < 0: sign_mult = -1 else: sign_mult = 1 return float(leading) + sign_mult * (float(num) / float(denom))

>>> convert_to_float(''3'') 3.0 >>> convert_to_float(''1/4'') 0.25 >>> convert_to_float(''1 2/3'') 1.6666666666666665 >>> convert_to_float(''-2/3'') -0.6666666666666666 >>> convert_to_float(''-3 1/2'') -3.5


Yo pellizqué un poco la respuesta de James .

def convert_to_float(frac_str): try: return float(frac_str) except ValueError: num, denom = frac_str.split(''/'') try: leading, num = num.split('' '') whole = float(leading) except ValueError: whole = 0 frac = float(num) / float(denom) return whole - frac if whole < 0 else whole + frac print convert_to_float(''3'') # 3.0 print convert_to_float(''3/2'') # 1.5 print convert_to_float(''1 1/2'') # 1.5 print convert_to_float(''-1 1/2'') # -1.5

http://ideone.com/ItifKv


tal vez algo como esto (2.6+)

from fractions import Fraction float(sum(Fraction(s) for s in ''1 2/3''.split()))


def fractionToFloat(fraction): num = 0 mult = 1 if fraction[:1] == "-": fraction = fraction[1:] mult = -1 if " " in fraction: a = fraction.split(" ") num = float(a[0]) toSplit = a[1] else: toSplit = fraction frac = toSplit.split("/") num += float(frac[0]) / float(frac[1]) return num * mult

También puede manejar "2 1 / 1e-8", "-1/3" y "1 / 5e3".


>>> s="1/2" >>> eval(''/''.join(map(str,map(float,s.split("/"))))) 0.5 >>> s="3/5" >>> eval(''/''.join(map(str,map(float,s.split("/"))))) 0.59999999999999998