這應該是儘可能地快:
''.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
修復喲ur'return'語句 – jamylak
完成這是一個錯字 – user2144553