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

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/575925/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-11-03 20:23:34  来源:igfitidea点击:

How to convert rational and decimal number strings to floats in python?

pythonrational-numbers

提问by ketorin

How can I convert strings which can denote decimal or rational numbers to floats

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

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

I'd want [0.1234, 0.5].

我想要 [0.1234, 0.5]。

eval is what I was thinking but no luck:

eval 是我在想的,但没有运气:

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

回答by Ryan

I'd parse the string if conversion fails:

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

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

Generally using eval is a bad idea, since it's a security risk. Especiallyif the string being evaluated came from outside the system.

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

回答by John Fouhy

As others have pointed out, using evalis potentially a security risk, and certainly a bad habit to get into. (if you don't think it's as risky as exec, imagine evaling something like: __import__('os').system('rm -rf /'))

正如其他人指出的那样,使用eval可能存在安全风险,而且肯定是一个不好养成的习惯。(如果你不认为这是有风险的exec,想象的eval荷兰国际集团这样的:__import__('os').system('rm -rf /')

However, if you have python 2.6 or up, you can use ast.literal_eval, for which the string provided:

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

may only consist of the following Python literal structures: strings, numbers, tuples, lists, dicts, booleans, and None.

可能只包含以下 Python 文字结构:字符串、数字、元组、列表、字典、布尔值和无。

Thus it should be quite safe :-)

因此它应该很安全:-)

回答by pantsgolem

Another option (also only for 2.6 and up) is the fractionsmodule.

另一个选项(也仅适用于 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

回答by kquinn

Use from __future__ import divisionto get the behavior you want. Then, in a pinch, you can do something like

使用from __future__ import division得到你想要的行为。然后,在紧要关头,你可以做类似的事情

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

to get a list of floats out of your strings. If you want to do this the "right" way, don't use eval(), but instead write a function that accepts a string and calls float()on it if it contains no slash, or parses the string and divides the numerator and denominator if there's a slash in it.

从字符串中获取浮点数列表。如果您想以“正确”的方式执行此操作,请不要使用eval(),而是编写一个函数,该函数接受一个字符串并float()在它不包含斜杠时调用它,或者解析字符串并在有斜杠时除以分子和分母在里面。

One way to do it:

一种方法:

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

Then just map(parse_float_string, strings)will get you your list.

然后map(parse_float_string, strings)就会给你你的清单。

回答by Greg Hewgill

The /operator does integer division. Try:

/运营商做整数除法。尝试:

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

Because eval()is potentially dangerous, you should always check precisely what you are passing into it:

因为eval()有潜在危险,所以您应该始终准确检查您传递给它的内容:

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

However, if you go to the trouble of matching the input against a regex in the first place, you might as well use r"(\d+)/(\d+)$"to extract the numerator and denominator, do the division yourself, and entirely avoid eval():

但是,如果您首先遇到将输入与正则表达式匹配的麻烦,您不妨使用r"(\d+)/(\d+)$"提取分子和分母,自己进行除法,并完全避免eval()

>>> m = re.match(r"(\d+)/(\d+)$", s)
>>> if m:
...     float(m.group(1)) / float(m.group(2))
...
0.5

回答by pavpanchekha

The problem with eval is that, as in python, the quotient of integers is an integer. So, you have several choices.

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

The first is simply to make integer division return floats:

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

from __future__ import division

The other is to split the rational number:

另一种是对有理数进行拆分:

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

Where rat_str is the string with a rational number.

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

回答by riza

In Python 3, this should work.

在 Python 3 中,这应该可以工作。

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

回答by Ignacio Vazquez-Abrams

sympycan help you out here:

sympy可以在这里帮助你:

import sympy

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

回答by MrTopf

That's because 1 and 2 are interpreted by Python as integers and not floats. It needs to be 1.0/2.0 or some mix of that.

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

回答by Andrew Jaffe

The suggestions with from __future__ import divisioncombined with evalwill certainly work.

from __future__ import division结合的建议eval肯定会奏效。

It's probably worth pointing out that the suggestions that don't use evalbut rather parse the string do so because evalis dangerous: if there is some way for an arbitrary string to get sent to eval, then your system is vulnerable. So it's a bad habit. (But if this is just quick and dirty code, it's probably not thatbig a deal!)

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