Pregunta

I quiere hacer una función que convierte mezclado números y fracciones (cadenas) a flotadores. He aquí algunos ejemplos:

'1 1/2' -> 1.5
'11/2' -> 5.5
'7/8' -> 0.875
'3' -> 3
'7.7' -> 7.7

Actualmente estoy usando esta función, pero creo que podría mejorarse. También no maneja los números que ya están en representación decimal

def mixedtofloat(txt):

    mixednum = re.compile("(\\d+) (\\d+)\\/(\\d+)",re.IGNORECASE|re.DOTALL)
    fraction = re.compile("(\\d+)\\/(\\d+)",re.IGNORECASE|re.DOTALL)
    integer = re.compile("(\\d+)",re.IGNORECASE|re.DOTALL)

    m = mixednum.search(txt)
    n = fraction.search(txt)
    o = integer.search(txt)

    if m:
        return float(m.group(1))+(float(m.group(2))/float(m.group(3)))
    elif n:
        return float(n.group(1))/float(n.group(2))
    elif o:
        return float(o.group(1))
    else:
        return txt

Gracias!

¿Fue útil?

Solución

2.6 tiene la fractions módulo. Sólo dividir la cadena en el espacio en blanco, alimentar a los trozos de fractions.Fraction(), float() llamada contra el resultado, y les añada todo.

Otros consejos

La respuesta de Ignacio es probablemente la mejor manera de manejar la situación, pero si usted no está utilizando Python 2.6, se puede construir una función que hace las cosas un poco más sencilla sin tener que depender de las expresiones regulares. Aquí está una versión simple y no muy robusto Tiré juntos:

def parse_fraction(fraction):

    def parse_part(part):
        sections = part.split('/')
        if len(sections) == 1:
            return float(sections[0])
        return float(sections[0]) / float(sections[1])

    return sum( parse_part(part) for part in fraction.split() )

Esto obviamente no es perfecta, ya que aún aceptará la entrada como '2 1/2 1/2', que se evaluaría como 3, ya que básicamente resume una lista de números espacio delimitado, mientras que la evaluación de cada uno como una fracción que sea necesario.

si lo hace con el palo de la solución basada en la expresión regular, usted debe saber que se puede utilizar una cadena de texto para evitar tener que doble barra invertida todo. En esencia, se puede escribir:

mixednum = re.compile(r"(\d+) (\d+)/(\d+)")

El r frente a la cadena le dice a Python para no evaluar caracteres especiales dentro de la cadena, para que pueda escribir barras invertidas literales y serán tratados como tales. También tenga en cuenta que no es necesario para escapar de la barra, ya que no es un carácter especial en las expresiones regulares de Python (porque no se utiliza para marcar los límites de la expresión regular literal como en muchos idiomas). la bandera re.IGNORECASE Tampoco tiene mucho sentido aquí, ya que sólo incluye a las entidades numéricas en la expresión regular, y re.DOTALL también tiene sentido, ya que no tiene puntos para que se aplique a.

Me escribió la clase Mixed extender fracciones de hacer precisamente eso. Fuente es aquí .

>>> float(Mixed('6 7/8'))
6.875
>>> float(Mixed(1,1,2)) # 1 1/2
1.5
>>> float(Mixed('11/2')) # 11/2
5.5
Licenciado bajo: CC-BY-SA con atribución
No afiliado a StackOverflow
scroll top