检查字符串是否可以在 Python 中表示为数字的最佳方法是什么?
我目前拥有的功能是:
def is_number(s):
try:
float(s)
return True
except ValueError:
return False
这不仅是丑陋而且缓慢,似乎很笨重。但是我没有找到更好的方法,因为在 main 函数中调用float
更糟糕。
如果您正在寻找解析(正,无符号)整数而不是浮点数,则可以对字符串对象使用isdigit()
函数。
>>> a = "03523"
>>> a.isdigit()
True
>>> b = "963spam"
>>> b.isdigit()
False
在 Unicode 字符串上也有一些东西,我对 Unicode 不太熟悉- 是十进制 / 十进制
其中,不仅是丑陋而且缓慢
我两个都有争议。
正则表达式或其他字符串解析将更加丑陋和缓慢。
我不确定任何事情都可能比上面更快。它调用函数并返回。 Try / Catch 不会引入太多开销,因为最常见的异常是在没有大量搜索堆栈帧的情况下捕获的。
问题是任何数字转换函数都有两种结果
C(作为一个例子)以多种方式解决这个问题。 Python 明确而明确地阐述了它。
我认为你这样做的代码是完美的。
TL; DR最好的解决方案是s.replace('.','',1).isdigit()
我做了一些比较不同方法的基准
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__)
不支持科学记数法 “1.000000e + 50”:
- is_number_regex
- is_number_repl_isdigit
不支持科学记数法 “1e50”:
- 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()