检查字符串是否可以在Python中表示为数字的最佳方法是什么?
我目前拥有的功能是:
def is_number(s):
try:
float(s)
return True
except ValueError:
return False
不仅丑陋且缓慢,而且看起来笨拙。 但是我还没有找到更好的方法,因为在main函数中调用float更加糟糕。
#1楼
这个怎么样:
'3.14'.replace('.','',1).isdigit()
仅当存在一个或不存在“。”时,它才返回true。 在数字字符串中。
'3.14.5'.replace('.','',1).isdigit()
将返回假
编辑:刚刚看到另一条评论...可以为其他情况添加.replace(badstuff,'',maxnum_badstuff) 。 如果您传递盐而不是任意调味品(ref: xkcd#974 ),这将很好:P
#2楼
这是我执行此操作的简单方法。 假设我正在遍历一些字符串,并且如果它们最终是数字,我想将它们添加到数组中。
try:
myvar.append( float(string_to_check) )
except:
continue
如果结果是数字,则将myvar.apppend替换为要对字符串进行的任何操作。 这个想法是尝试使用float()操作并使用返回的错误来确定字符串是否为数字。
#3楼
我想看看哪种方法最快。 总的来说,最好和最一致的结果由check_replace函数给出。 最快的结果是由check_exception函数给出的,但check_exception是没有check_exception异常-这意味着其代码是最有效的,但是引发异常的开销非常大。
请注意,检查是否成功进行了check_exception是唯一准确的方法,例如,此方法可与check_exception一起check_exception但其他两个测试函数对于有效的浮点数将返回False:
huge_number = float('1e+100')
这是基准代码:
import time, re, random, string
ITERATIONS = 10000000
class Timer:
def __enter__(self):
self.start = time.clock()
return self
def __exit__(self, *args):
self.end = time.clock()
self.interval = self.end - self.start
def check_regexp(x):
return re.compile("^\d*\.?\d*$").match(x) is not None
def check_replace(x):
return x.replace('.','',1).isdigit()
def check_exception(s):
try:
float(s)
return True
except ValueError:
return False
to_check = [check_regexp, check_replace, check_exception]
print('preparing data...')
good_numbers = [
str(random.random() / random.random())
for x in range(ITERATIONS)]
bad_numbers = ['.' + x for x in good_numbers]
strings = [
''.join(random.choice(string.ascii_uppercase + string.digits) for _ in range(random.randint(1,10)))
for x in range(ITERATIONS)]
print('running test...')
for func in to_check:
with Timer() as t:
for x in good_numbers:
res = func(x)
print('%s with good floats: %s' % (func.__name__, t.interval))
with Timer() as t:
for x in bad_numbers:
res = func(x)
print('%s with bad floats: %s' % (func.__name__, t.interval))
with Timer() as t:
for x in strings:
res = func(x)
print('%s with strings: %s' % (func.__name__, t.interval))
以下是2017年MacBook Pro 13上Python 2.7.10的结果:
check_regexp with good floats: 12.688639
check_regexp with bad floats: 11.624862
check_regexp with strings: 11.349414
check_replace with good floats: 4.419841
check_replace with bad floats: 4.294909
check_replace with strings: 4.086358
check_exception with good floats: 3.276668
check_exception with bad floats: 13.843092
check_exception with strings: 15.786169
以下是2017年MacBook Pro 13上使用Python 3.6.5的结果:
check_regexp with good floats: 13.472906000000009
check_regexp with bad floats: 12.977665000000016
check_regexp with strings: 12.417542999999995
check_replace with good floats: 6.011045999999993
check_replace with bad floats: 4.849356
check_replace with strings: 4.282754000000011
check_exception with good floats: 6.039081999999979
check_exception with bad floats: 9.322753000000006
check_exception with strings: 9.952595000000002
以下是2017年MacBook Pro 13上PyPy 2.7.13的结果:
check_regexp with good floats: 2.693217
check_regexp with bad floats: 2.744819
check_regexp with strings: 2.532414
check_replace with good floats: 0.604367
check_replace with bad floats: 0.538169
check_replace with strings: 0.598664
check_exception with good floats: 1.944103
check_exception with bad floats: 2.449182
check_exception with strings: 2.200056
#4楼
您可以使用Unicode字符串,它们有一种方法可以执行您想要的操作:
>>> s = u"345"
>>> s.isnumeric()
True
要么:
>>> s = "345"
>>> u = unicode(s)
>>> u.isnumeric()
True
http://www.tutorialspoint.com/python/string_isnumeric.htm
http://docs.python.org/2/howto/unicode.html
#5楼
您可以通过返回比True和False更有用的值,以有用的方式概括异常技术。 例如,此函数将引号括在字符串中,但不留数字。 这正是我快速而肮脏的过滤器为R定义变量所需要的。
import sys
def fix_quotes(s):
try:
float(s)
return s
except ValueError:
return '"{0}"'.format(s)
for line in sys.stdin:
input = line.split()
print input[0], '<- c(', ','.join(fix_quotes(c) for c in input[1:]), ')'
来源:oschina
链接:https://my.oschina.net/stackoom/blog/3138644