Nic*_*oul 42 python string performance startswith case-insensitive
以下是我如何检查是否mystring以某个字符串开头:
>>> mystring.lower().startswith("he")
True
Run Code Online (Sandbox Code Playgroud)
问题是mystring很长(数千个字符),所以lower()操作需要很多时间.
问题:有更有效的方法吗?
我不成功的尝试:
>>> import re;
>>> mystring.startswith("he", re.I)
False
Run Code Online (Sandbox Code Playgroud)
NPE*_*NPE 48
您可以使用正则表达式,如下所示:
In [33]: bool(re.match('he', 'Hello', re.I))
Out[33]: True
In [34]: bool(re.match('el', 'Hello', re.I))
Out[34]: False
Run Code Online (Sandbox Code Playgroud)
在2000个字符的字符串上,这比lower()以下快20倍:
In [38]: s = 'A' * 2000
In [39]: %timeit s.lower().startswith('he')
10000 loops, best of 3: 41.3 us per loop
In [40]: %timeit bool(re.match('el', s, re.I))
100000 loops, best of 3: 2.06 us per loop
Run Code Online (Sandbox Code Playgroud)
如果您重复匹配相同的前缀,预编译正则表达式会产生很大的差异:
In [41]: p = re.compile('he', re.I)
In [42]: %timeit p.match(s)
1000000 loops, best of 3: 351 ns per loop
Run Code Online (Sandbox Code Playgroud)
对于简短的前缀,在将字符串转换为小写之前将字符串切除,可能会更快:
In [43]: %timeit s[:2].lower() == 'he'
1000000 loops, best of 3: 287 ns per loop
Run Code Online (Sandbox Code Playgroud)
这些方法的相对时间当然取决于前缀的长度.在我的机器上,盈亏平衡点似乎是六个字符,这是预编译的正则表达式成为最快的方法.
在我的实验中,分别检查每个字符可能更快:
In [44]: %timeit (s[0] == 'h' or s[0] == 'H') and (s[1] == 'e' or s[1] == 'E')
1000000 loops, best of 3: 189 ns per loop
Run Code Online (Sandbox Code Playgroud)
但是,此方法仅适用于编写代码时已知的前缀,并且不适用于较长的前缀.
ins*_*get 25
这个怎么样:
prefix = 'he'
if myVeryLongStr[:len(prefix)].lower() == prefix.lower()
Run Code Online (Sandbox Code Playgroud)
另一个简单的解决方案是将一个元组传递startswith()给所有需要匹配的情况,例如.startswith(('case1', 'case2', ..)).
例如:
>>> 'Hello'.startswith(('He', 'HE'))
True
>>> 'HEllo'.startswith(('He', 'HE'))
True
>>>
Run Code Online (Sandbox Code Playgroud)
| 归档时间: |
|
| 查看次数: |
34959 次 |
| 最近记录: |