Это должно быть как можно быстрее:
''.join([coder[i] if i in coder else i for i in text])
описаний списков гораздо более оптимизированы в Python по сравнению с for
петлями, которые несут большую нагрузку. Я передал понимание списка в отличие от генератора в ''.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
из-за этого, но я не думал, что это сильно повлияет. В любом случае, понимание списка по-прежнему выигрывает.
Update: Если изменить 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
(2-й тест) ->27.1162974624
Fix yo ur 'return' statement – jamylak
сделал это опечатка – user2144553