[英]Efficiently check if string contains a digit in python
我有大量 (GB) 的文本要逐句處理。 在每個句子中,我都要對數字執行昂貴的操作,所以我檢查這個句子是否至少包含一個數字。 我使用不同的方法完成了這項檢查,並使用timeit
測量了這些解決方案。
s = 'abcdefghijklmnopqrstuvwxyzabcdefghijklmnopqrstuvwxyz' # example
any(c.isdigit() for c in s)
3.61 µs
re.search('\d', s)
402 ns
d = re.compile('\d')
d.search(s)
126 ns
'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
60ns
最后一種方法是最快的,但它很丑,可能比可能的慢 10 倍。
當然,我可以用 cython 重寫它,但這似乎有點矯枉過正。
有更好的純python解決方案嗎? 特別是,我想知道為什么您可以將str.startswith()
和str.endswith()
與元組參數一起使用,但使用in
運算符似乎不可能。
實際性能可能會因您的平台和 python 版本而異,但根據我的設置(python 3.9.5 / Ubuntu),事實證明re.match
比re.search
快得多,並且優於 long in
series 版本。 此外,使用[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%。 它看起來也更好。
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.