php's strtr для python
PHP имеетstrtr
функция:
strtr('aa-bb-cc', array('aa' => 'bbz', 'bb' => 'x', 'cc' => 'y'));
# bbz-x-y
Он заменяет словарные ключи в строке соответствующими значениями и (что важно) не заменяет уже замененные строки. Наивная попытка написать то же самое на python:
def strtr(strng, replace):
for s, r in replace.items():
strng = strng.replace(s, r)
return strng
strtr('aa-bb-cc', {'aa': 'bbz', 'bb': 'x', 'cc': 'y'})
возвращаетсяxz-x-y
чего мы не хотим (bb
получил замену снова). Как изменить вышеупомянутую функцию так, чтобы она вела себя как ее аналог php?
(Я бы предпочел ответ без регулярных выражений, если это возможно).
Upd: некоторые отличные ответы здесь. Я рассчитал их и обнаружил, что для коротких струн Gumbo-версия оказывается самой быстрой, а для длинных струн победителем становитсяre
решение:
# 'aa-bb-cc'
0.0258 strtr_thg
0.0274 strtr_gumbo
0.0447 strtr_kojiro
0.0701 strtr_aix
# 'aa-bb-cc'*10
0.1474 strtr_aix
0.2261 strtr_thg
0.2366 strtr_gumbo
0.3226 strtr_kojiro
Моя собственная версия (которая немного оптимизирована для Gumbo):
def strtr(strng, replace):
buf, i = [], 0
while i < len(strng):
for s, r in replace.items():
if strng[i:len(s)+i] == s:
buf.append(r)
i += len(s)
break
else:
buf.append(strng[i])
i += 1
return ''.join(buf)
Полные коды и сроки:https://gist.github.com/2889181