有效检查字符串是否包含 python 中的数字

Efficiently check if string contains a digit in python

我有大量 (GB) 的文本要逐句处理。 在每个句子中,我都要对数字执行代价高昂的操作,因此我检查该句子是否至少包含一位数字。 我使用不同的方式完成了这项检查,并使用 timeit.

测量了这些解决方案

s = 'abcdefghijklmnopqrstuvwxyzabcdefghijklmnopqrstuvwxyz' # example

最后一种方法是最快的,但它很丑,而且可能比可能的方法慢 10 倍。

当然我可以用 cython 重写它,但这似乎有点过分了。

是否有更好的纯python解决方案?特别是,我想知道为什么您可以将 str.startswith()str.endswith() 与元组参数一起使用,但似乎无法使用 in 运算符。

实际性能可能因您的平台和 python 版本而异,但在我的设置中 (python 3.9.5 / Ubuntu),结果是 re.match 明显快于 re.search,并且优于长 in 系列版本。此外,使用 [0-9] 而不是 \d 编译正则表达式提供了一点改进。

import re
from timeit import timeit

n = 10_000_000
s = 'abcdefghijklmnopqrstuvwxyzabcdefghijklmnopqrstuvwxyz'

# reference
timeit(lambda: '0' in s or '1' in s or '2' in s or '3' in s or '4' in s or '5' in s or '6' in s or '7' in s or '8' in s or '9' in s, number=n)
# 2.1005349759998353

# re.search with \d, slower
re.compile('\d')
timeit(lambda: d.search(s), number=n)
# 2.9816031390000717

# re.search with [0-9], better but still slower then reference
d = re.compile('[0-9]')
timeit(lambda: d.search(s), number=n)
# 2.640713582999524

# re.match with [0-9], faster than reference
d = re.compile('[0-9]')
timeit(lambda: d.match(s), number=n)
# 1.5671786130005785

所以,在我的机器上,使用 re.match 和编译的 [0-9] 模式比长 or ... in 链接快大约 25% .而且看起来也更好。