我想使用Python 2.6及更高版本将字符串转换为浮点数,但没有以静默方式将'NaN'
和'Inf'
之类的内容转换为浮动对象。我确实希望它们被默默地忽略,就像任何无效的浮动表示文本一样。
在2.6之前,float("NaN")
会在Windows上引发ValueError。现在它返回一个float,math.isnan()返回True,这对我的应用程序来说没有用处。 (正如所指出的,这一直是一种依赖于平台的行为,但考虑到我的目的,无论发生在哪里,都认为这是一种不受欢迎的行为。)
这就是我现在所拥有的:
import math
def get_floats(source):
for text in source.split():
try:
val = float(text)
if math.isnan(val) or math.isinf(val):
raise ValueError
yield val
except ValueError:
pass
这是一个生成器,我可以提供包含表示实数的空格分隔序列的字符串。我希望它只产生那些纯粹是浮动数字表示的字段,如“1.23”或“-34e6”,但不是例如“NaN”或“-Inf”。根本不浮动的东西,例如“你好”,也应该被忽略。
测试用例:
assert list(get_floats('1.23 foo -34e6 NaN -Inf')) == [1.23, -34000000.0]
请提出您认为更优雅的替代方案,即使它们涉及“在您跳跃之前”(通常被认为是Python中较小的方法)。
编辑以澄清非浮动文本,例如“hello”也应该被忽略。目的是只取出那些真实数字而忽略其他一切的东西。
答案 0 :(得分:2)
def is_finite(x):
return not math.isnan(x) and not math.isinf(x)
def get_floats(source):
for x in source.split():
try:
yield float(x)
except ValueError:
pass
def get_finite_floats(source):
return (x for x in get_floats(source) if is_finite(x))
答案 1 :(得分:1)
这是一个非常小的建议,但continue
比提出异常要快一点:
def get_floats(source):
for text in source.split():
try:
val = float(text)
if math.isnan(val) or math.isinf(val): continue
yield val
except ValueError:
pass
使用raise ValueError
:
% python -mtimeit -s'import test' "list(test.get_floats('1.23 -34e6 NaN -Inf Hello'))"
10000 loops, best of 3: 22.3 usec per loop
使用continue
:
% python -mtimeit -s'import test' "list(test.get_floats_continue('1.23 -34e6 NaN -Inf Hello'))"
100000 loops, best of 3: 17.2 usec per loop
答案 2 :(得分:0)
我投了Paul Hankin的答案是为了提高可读性,但是如果我不想将代码分开,那么这里的原始变体就不那么笨重了。
def get_only_numbers(source):
'''yield all space-separated real numbers in source string'''
for text in source.split():
try:
val = float(text)
except ValueError:
pass # ignore non-numbers
else:
# "NaN", "Inf" get converted: explicit test to ignore them
if not math.isnan(val) and not math.isinf(val):
yield val
与我原来的情况相差甚远。
答案 3 :(得分:0)
怎么样
[]