如何在python中将有理数和十进制数字串转换为浮点数?

时间:2009-02-22 22:08:48

标签: python rational-numbers

如何将可以表示十进制或有理数的字符串转换为浮点数

>>> ["0.1234", "1/2"]
['0.1234', '1/2']

我想要[0.1234,0.5]。

是的,我正在思考,但没有运气:

>>> eval("1/2")
0

10 个答案:

答案 0 :(得分:16)

如果转换失败,我会解析字符串:

>>> def convert(s):
    try:
        return float(s)
    except ValueError:
        num, denom = s.split('/')
        return float(num) / float(denom)
...

>>> convert("0.1234")
0.1234

>>> convert("1/2")
0.5

通常使用eval是一个坏主意,因为它存在安全风险。 特别是,如果被评估的字符串来自系统外部。

答案 1 :(得分:7)

正如其他人所指出的那样,使用eval可能会带来安全风险,当然也是一种不好的习惯。 (如果您认为它不像exec那样有风险,请想象eval类似:__import__('os').system('rm -rf /')

但是,如果你有python 2.6或更高版本,你可以使用ast.literal_eval,为其提供字符串:

  

可能只包含以下内容   Python文字结构:字符串,   数字,元组,列表,dicts,   布尔,没有。

因此它应该是非常安全的: - )

答案 2 :(得分:6)

另一个选项(也仅适用于2.6及更高版本)是fractions模块。

>>> from fractions import Fraction
>>> Fraction("0.1234")
Fraction(617, 5000)
>>> Fraction("1/2")
Fraction(1, 2)
>>> float(Fraction("0.1234"))
0.1234
>>> float(Fraction("1/2"))
0.5

答案 3 :(得分:4)

使用from __future__ import division获取所需的行为。然后,在紧要关头,你可以做类似

的事情
from __future__ import division
strings = ["0.1234", "1/2", "2/3"]
numbers = map(eval, strings)

从字符串中获取浮点数列表。如果你想以“正确”的方式做到这一点,不要使用eval(),而是编写一个接受字符串的函数,如果它不包含斜杠,则调用float(),或者解析字符串如果中有斜线,则除以分子和分母。

一种方法:

def parse_float_string(x)
    parts = x.split('/', 1)
    if len(parts) == 1:
        return float(x)
    elif len(parts) == 2:
        return float(parts[0])/float(parts[1])
    else:
        raise ValueError

然后只需map(parse_float_string, strings)即可获得您的清单。

答案 4 :(得分:3)

/运算符执行整数除法。尝试:

>>> eval("1.0*" + "1/2")
0.5

由于eval()具有潜在的危险性,因此您应该始终准确地检查传入的内容:

>>> import re
>>> s = "1/2"
>>> if re.match(r"\d+/\d+$", s):
...     eval("1.0*" + s)
...
0.5

但是,如果您首先要将输入与正则表达式匹配,那么您也可以使用r"(\d+)/(\d+)$"提取分子和分母,自己进行除法,并完全避免{{ 1}}:

eval()

答案 5 :(得分:2)

eval的问题在于,就像在python中一样,整数的商是一个整数。所以,你有几个选择。

第一个是简单地使整数除法返回浮点数:

from __future__ import division

另一种是分裂有理数:

reduce(lambda x, y: x*y, map(int, rat_str.split("/")), 1)

其中rat_str是具有有理数的字符串。

答案 6 :(得分:1)

在Python 3中,这应该可行。

>>> x = ["0.1234", "1/2"]
>>> [eval(i) for i in x]
[0.1234, 0.5]

答案 7 :(得分:1)

sympy可以帮到你:

import sympy

half = sympy.Rational('1/2')
p1234 = sympy.Rational('0.1234')
print '%f, %f" % (half, p1234)

答案 8 :(得分:0)

那是因为1和2被Python解释为整数而不是浮点数。它需要是1.0 / 2.0或其中的一些混合。

答案 9 :(得分:0)

from __future__ import divisioneval相结合的建议肯定会有用。

可能值得指出的是,不使用eval而是解析字符串的建议是这样做的,因为eval是危险的:如果有任何方法可以将任意字符串发送到eval,那么您的系统容易受到攻击。所以这是一个坏习惯。 (但如果这只是快速而又脏的代码,那可能不是 大不了一样!)