如何检查字符串是否表示 Python 中的数值?
def is_number(s):
try:
float(s)
return True
except ValueError:
return False
上面的作品,但它似乎笨拙。
如果您正在测试的内容来自用户输入,则即使它表示int
或float
,它仍然是一个字符串。请参阅How can I read inputs as numbers?以转换输入,以及Asking the user for input until they give a valid response以确保输入表示int
或1)。

对于非负(无符号)整数,请使用isdigit()
:
>>> a = "03523"
>>> a.isdigit()
True
>>> b = "963spam"
>>> b.isdigit()
False
Documentation forisdigit()
:Python2,Python3
对于 Python 2 Unicode 字符串:isnumeric()
。

这不仅丑陋而且缓慢
我会两者都争论。
正则表达式或其他字符串解析方更丑陋和更慢。
我不确定任何东西都可能比上面更快。它调用函数并返回。Try / Catch 不会引入太多开销,因为最常见的异常是在没有广泛搜索堆栈帧的情况下捕获的。
问题是任何数值转换函数都有两种结果
一个数字,如果该数字有效
状态代码(例如,通过 errno)或异常,以显示无法解析有效数字。
C(作为一个例子)有很多方法可以解决这个问题。
我认为你这样做的代码是完美的。
TL;DR最好的解决方案是s.replace('.','',1).isdigit()
我做了一些benchmarks比较不同的方法
def is_number_tryexcept(s):
""" Returns True is string is a number. """
try:
float(s)
return True
except ValueError:
return False
import re
def is_number_regex(s):
""" Returns True is string is a number. """
if re.match("^\d+?\.\d+?$", s) is None:
return s.isdigit()
return True
def is_number_repl_isdigit(s):
""" Returns True is string is a number. """
return s.replace('.','',1).isdigit()
如果字符串不是数字,那么 except-block 就相当慢了。但更重要的是,try-except 方法是正确处理科学符号的唯一方法。
funcs = [
is_number_tryexcept,
is_number_regex,
is_number_repl_isdigit
]
a_float = '.1234'
print('Float notation ".1234" is not supported by:')
for f in funcs:
if not f(a_float):
print('\t -', f.__name__)
以下项不支持浮点表示法“.1234”:
-is_number_regex
scientific1 = '1.000000e+50'
scientific2 = '1e50'
print('Scientific notation "1.000000e+50" is not supported by:')
for f in funcs:
if not f(scientific1):
print('\t -', f.__name__)
print('Scientific notation "1e50" is not supported by:')
for f in funcs:
if not f(scientific2):
print('\t -', f.__name__)
-is_number_regex
-is_number_repl_isdigit
不支持科学记法“1.000000 e + 50”:
-is_number_regex
-is_number_repl_isdigit
编辑:基准测试结果
import timeit
test_cases = ['1.12345', '1.12.345', 'abc12345', '12345']
times_n = {f.__name__:[] for f in funcs}
for t in test_cases:
for f in funcs:
f = f.__name__
times_n[f].append(min(timeit.Timer('%s(t)' %f,
'from __main__ import %s, t' %f)
.repeat(repeat=3, number=1000000)))
其中测试了以下功能
from re import match as re_match
from re import compile as re_compile
def is_number_tryexcept(s):
""" Returns True is string is a number. """
try:
float(s)
return True
except ValueError:
return False
def is_number_regex(s):
""" Returns True is string is a number. """
if re_match("^\d+?\.\d+?$", s) is None:
return s.isdigit()
return True
comp = re_compile("^\d+?\.\d+?$")
def compiled_regex(s):
""" Returns True is string is a number. """
if comp.match(s) is None:
return s.isdigit()
return True
def is_number_repl_isdigit(s):
""" Returns True is string is a number. """
return s.replace('.','',1).isdigit()
您可能需要考虑一个例外:字符串 'NaN'
如果你想 is_number 为 'NaN' 返回 FALSE,这段代码将无法工作,因为 Python 将其转换为非数字的数字表示(谈论身份问题):
>>> float('NaN')
nan
否则,我实际上应该感谢你现在广泛使用的代码。:)
G.
本站系公益性非盈利分享网址,本文来自用户投稿,不代表码文网立场,如若转载,请注明出处
评论列表(20条)