Python - конвертировать смешанное число в число с плавающей точкой - PullRequest
3 голосов
/ 21 мая 2010

Я хочу создать функцию, которая преобразует смешанные числа и дроби (как строки) в числа с плавающей точкой. Вот несколько примеров:

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

В настоящее время я использую эту функцию, но думаю, что ее можно улучшить. Он также не обрабатывает числа, которые уже находятся в десятичном представлении

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

Спасибо!

Ответы [ 3 ]

8 голосов
/ 21 мая 2010

2.6 имеет модуль fractions. Просто разбейте строку на пустое пространство, введите куски в fractions.Fraction(), вызовите float() для результата и сложите их все.

2 голосов
/ 21 мая 2010

Ответ Игнасио, вероятно, лучший способ справиться с этим, но если вы не используете Python 2.6, вы можете создать функцию, которая делает вещи немного проще, не полагаясь на регулярные выражения. Вот простая и не очень надежная версия, которую я скинул вместе:

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

Это, очевидно, не идеально, потому что он по-прежнему будет принимать ввод, такой как '2 1/2 1/2', который он будет оценивать как 3, так как он по существу суммирует список чисел с разделителями пробелами, оценивая каждое как дробь по мере необходимости.

если вы придерживаетесь решения на основе регулярных выражений, вы должны знать, что вы можете использовать необработанную строку, чтобы избежать двойной обратной косой черты. По сути, вы можете написать:

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

r перед строкой говорит Python не оценивать специальные символы в строке, поэтому вы можете писать буквальные обратные слэши, и они будут рассматриваться как таковые. Также обратите внимание, что вам не нужно экранировать косую черту, поскольку она не является специальным символом в регулярных выражениях Python (поскольку она не используется для обозначения границ литерального регулярного выражения, как во многих языках). флаг re.IGNORECASE также не имеет большого смысла, поскольку он включает в себя только числовые объекты в регулярном выражении, а re.DOTALL также не имеет смысла, поскольку у вас нет точек, к которым он может применяться.

1 голос
/ 13 ноября 2013

Я написал класс Mixed для расширения дроби, чтобы сделать это. Источник здесь .

>>> 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
...