Question

Je veux faire une fonction qui permet de convertir des nombres fractionnaires et des fractions (sous forme de chaînes) à flotteurs. Voici quelques exemples:

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

J'utilise actuellement cette fonction, mais je pense qu'il pourrait être amélioré. Il ne gère pas aussi des chiffres qui sont déjà en représentation décimale

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

Merci!

Était-ce utile?

La solution

2,6 a le module fractions . Il suffit de diviser la chaîne sur les espaces, nourrir les morceaux à fractions.Fraction(), float() d'appel contre le résultat, et additionnez-les.

Autres conseils

La réponse de Ignacio est probablement la meilleure façon de le gérer, mais si vous ne l'utilisez Python 2.6, vous pouvez créer une fonction qui fait des choses un peu plus simplement sans avoir à compter sur les expressions régulières. Voici un simple et pas la version très robuste, je lançai ensemble:

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() )

Ceci est évidemment pas parfait, car il continue d'accepter l'entrée comme '2 1/2 1/2', qu'il évaluerait comme 3, puisqu'elle résume essentiellement une liste délimitée par l'espace des nombres tout en évaluant chacun comme une fraction si nécessaire.

si vous faites bâton avec la solution à base régulière expression, vous devez savoir que vous pouvez utiliser une chaîne brute pour éviter d'avoir à tout double barre oblique inverse. Essentiellement, vous pouvez écrire:

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

Le r en face de la chaîne indique Python pour ne pas évaluer des caractères spéciaux dans la chaîne, de sorte que vous pouvez écrire antislashs littérales et ils seront traités comme tels. Notez également que vous n'avez pas besoin d'échapper à la barre, car il n'est pas un caractère spécial dans les expressions régulières Python (car il ne sert pas à marquer les frontières de l'expression régulière littérale comme dans de nombreuses langues). le drapeau de re.IGNORECASE également ne fait pas beaucoup de sens ici, car elle ne comprend que les entités numériques dans l'expression rationnelle et re.DOTALL est aussi vide de sens, puisque vous avez pas de points pour l'appliquer à.

J'ai écrit la classe Mixed pour étendre les fractions à faire. Source est .

>>> 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
Licencié sous: CC-BY-SA avec attribution
Non affilié à StackOverflow
scroll top