这应该尽可能快:
''.join([coder[i] if i in coder else i for i in text])
for
与承受巨大开销的循环相比,Python 中的列表推导得到了更好的优化。我已经通过了列表理解而不是生成器,''.join
因为它必须在加入之前提前知道输入的长度。如果你给它一个生成器,它无论如何都必须把它变成一个列表(这有点慢)。
实际上,您可以进一步简化它,这应该更快
(由于方法调用,这实际上比上述方法执行得慢)
''.join([coder.get(i,i) for i in text])
时间:
def applyCoder(text, coder):
L = []
for i in text:
if i in coder:
L.append(coder[i])
else:
L.append(i)
return ''.join(L)
def list_comp(text, coder):
return ''.join([coder[i] if i in coder else i for i in text])
def list_comp2(text, coder):
return ''.join([coder.get(i,i) for i in text])
from timeit import timeit
from string import ascii_letters
d = dict(zip(ascii_letters, ascii_letters[3:] + ascii_letters[-3:]))
print timeit(stmt='applyCoder("Hello, world!", d)',
setup='from __main__ import applyCoder, d;')
print timeit(stmt='list_comp("Hello, world!", d)',
setup='from __main__ import list_comp, d;')
print timeit(stmt='list_comp2("Hello, world!", d)',
setup='from __main__ import list_comp2, d;')
print timeit(stmt='applyCoder("Hello, world!"*10, d)',
setup='from __main__ import applyCoder, d;')
print timeit(stmt='list_comp("Hello, world!"*10, d)',
setup='from __main__ import list_comp, d;')
print timeit(stmt='list_comp2("Hello, world!"*10, d)',
setup='from __main__ import list_comp2, d;')
结果:
''' Test 1 '''
5.0159105417 # applyCoder
3.41502481461 # listcomp1
4.76796932292 # listcomp2
''' Test 2 '''
34.9718502631 # applyCoder
22.0451702661 # listcomp1
34.1682597928 # listcomp2
似乎该方法调用coder.get
完全否定了列表理解的优点。我确实预测它可能会因此而变慢listcomp1
,但我认为它不会产生如此大的影响。无论如何,列表理解仍然获胜。
更新:
如果你list_comp2
这样修改:
def list_comp2(text, coder):
coder_get = coder.get
return ''.join([coder_get(i,i) for i in text])
时代进步很大:
从4.76796932292
(第一次测试)->3.95217394948
和34.1682597928
(第二次测试)->27.1162974624