将分数转换为浮点数?

时间:2009-11-27 00:36:10

标签: python parsing

有点like this question,但相反。

给定11/21 2/3之类的字符串,将其转换为浮点数的最佳方法是什么?我正在考虑逐个使用正则表达式,但也许有人知道更好的方法,或者预先存在的解决方案。我希望我可以使用eval,但我认为第三种情况可以防止这种情况。

9 个答案:

答案 0 :(得分:35)

可能是这样的(2.6 +)

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

答案 1 :(得分:7)

我稍微调整了James' answer

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

答案 2 :(得分:6)

虽然你应该完全避开eval。也许是一些更精致的版本:

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

对不起,意思是num.split而不是s.split和强制转换。编辑。

答案 3 :(得分:3)

我看到这里已经有好几个好的答案了,但我运气好了。它还有一个好处,即如果你正在解析混合数据集,它将容忍非分数字符串,所以不需要检查它是否是一个分数字符串或不是前期。

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

答案 4 :(得分:2)

这可能是一个肮脏的解决方法,但您可以将空格转换为+符号以解决第三种情况(如果您的分数为负数,则转换为-

答案 5 :(得分:2)

此实现避免使用eval并适用于2.6之前的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)

测试:

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

答案 6 :(得分:2)

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

它还可以处理“2 1 / 1e-8”,“ - 1/3”和“1 / 5e3”。

答案 7 :(得分:0)

根据您希望为分数支持的语法,eval('+'.join(s.split()))(具有真正的分区 - 即Python 3中的Python 3或from __future__ import division - 可能会有效。它将涵盖所有你提到的案例,特别是。

答案 8 :(得分:0)

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