Convert fraction to float?

2019-01-11 23:07发布

Kind of like this question, but in reverse.

Given a string like 1, 1/2, or 1 2/3, what's the best way to convert it into a float? I'm thinking about using regexes on a case-by-case basis, but perhaps someone knows of a better way, or a pre-existing solution. I was hoping I could just use eval, but I think the 3rd case prevents that.

9条回答
smile是对你的礼貌
2楼-- · 2019-01-11 23:29

maybe something like this (2.6+)

from fractions import Fraction
float(sum(Fraction(s) for s in '1 2/3'.split()))
查看更多
地球回转人心会变
3楼-- · 2019-01-11 23:29

Depending on what syntax you want to support for your fractions, eval('+'.join(s.split())) (with true division in place -- i.e., Python 3 or from __future__ import division in Python 2 -- might work. It would cover all the cases you mention, in particular.

查看更多
太酷不给撩
4楼-- · 2019-01-11 23:33

I tweaked James' answer a bit.

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

查看更多
Ridiculous、
5楼-- · 2019-01-11 23:39
>>> 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
查看更多
手持菜刀,她持情操
6楼-- · 2019-01-11 23:40

I see there are already several good answers here, but I've had good luck with this. It also has the benefit that it will tolerate non-fraction strings if you're parsing mixed sets of data, so there's no need to check if it's a fraction string or not upfront.

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
查看更多
再贱就再见
7楼-- · 2019-01-11 23:42

This implementation avoids using eval and works on pre-2.6 versions of 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: return i  # if d is None, then n is also None
  if n is None: i, n = 0, i
  return float(i) + float(n) / float(d)

To test:

>>> for x in ['1', '1/2', '1 2/3']: print parse(x)
... 
1
0.5
1.66666666667
查看更多
登录 后发表回答