[英]Optimizing execution-time to check if chars of a word are in a list python
我正在编写python2.7.15代码来访问单词中的字符。 我如何优化此过程,以便还检查每个单词是否包含在外部列表中?
我已经尝试了两个版本的python2代码:version(1)是我的代码必须执行的扩展版本,而在版本(2)中,我尝试了相同代码的紧凑版本。
chars_array = ['a','b','c']
VERSION (1)
def version1(word):
chars =[x for x in word]
count = 0
for c in chars:
if not c in chars_array:
count+=1
return count
VERSION (2)
def version2(word):
return sum([1 for c in [x for x in word] if not c in chars_array])
我正在分析一个大型语料库,对于version1,我获得的执行时间为8.56秒,而对于version2,它的执行时间为8.12秒。
最快的解决方案(对于极长的字符串,最快可以提高100倍):
joined = ''.join(chars_array)
def version3(word):
return len(word.translate(None, joined))
另一个较慢的解决方案,其速度与您的代码大致相同:
from itertools import ifilterfalse
def version4(word):
return sum(1 for _ in ifilterfalse(set(chars_array).__contains__, word))
时间( s
是随机字符串):
In [17]: %timeit version1(s)
1000 loops, best of 3: 79.9 µs per loop
In [18]: %timeit version2(s)
10000 loops, best of 3: 98.1 µs per loop
In [19]: %timeit version3(s)
100000 loops, best of 3: 4.12 µs per loop # <- fastest
In [20]: %timeit version4(s)
10000 loops, best of 3: 84.3 µs per loop
与chars_array = ['a', 'e', 'i', 'o', 'u', 'y']
和words
等于56048个英字列表,我所测量的多种变体具有相似的命令在IPython提示符下执行以下操作:
%timeit n = [version1(word) for word in words]
在每种情况下,它都报告“ 10个循环,最好3个”,并且在下面每个函数定义旁边的注释中显示了每个循环的时间:
# OP's originals:
def version1(word): # 163 ms
chars =[x for x in word]
count = 0
for c in chars:
if not c in chars_array:
count+=1
return count
def version2(word): # 173 ms
return sum([1 for c in [x for x in word] if not c in chars_array])
现在让我们通过三个优化来实现version1
和version2
:
word
进行迭代; not in
运算符not in
而不是否定in
运算符的结果; set
而不是list
)的(非)成员身份。 _
chars_set = set(chars_array)
def version1a(word): # 95.5 ms
count = 0
for c in word:
if c not in chars_set:
count+=1
return count
def version2a(word): # 104 ms
return sum([1 for c in word if c not in chars_set])
因此,多行代码实际上比列表理解有一个优势。 但是,这可能取决于单词的长度: version2a
必须分配一个与单词长度相同的新列表,而version1a
则不需要。 让我们通过对生成器表达式求和而不是对列表求和进行求和,进一步完善version2a
以获得相同的优势:
def version2b(word): # 111 ms
return sum(1 for c in word if c not in chars_set)
令我惊讶的是,这实际上适得其反,但同样的,效果可能取决于字长。
最后,让我们体验一下.translate()
的强大.translate()
:
chars_str = ''.join(chars_set)
def version3(word): # 40.7 ms
return len(word.translate(None, chars_str))
我们有一个明确的赢家。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.