2013-09-29 2 views
1

У меня есть словарь со всеми ключами три буквы длинными: threeLetterDict={'abc': 'foo', 'def': 'bar', 'ghi': 'ha' ...}затруднительное re.sub со словарем

Теперь мне нужно перевести предложение abcdefghi в foobarha. Я пытаюсь метод ниже с re.sub, но не знаю, как поставить словарь в него:

p = re.compile('.{3}') # match every three letters 
re.sub(p,'how to put dictionary here?', "abcdefghi") 

Спасибо! (Нет необходимости, чтобы проверить, если длина входной кратно трем)

ответ

3

Вы можете передавать любые отозваны в re.sub, так:

p.sub(lambda m: threeLetterDict[m.group(0)], "abcdefghi") 

It works!

+0

Я не famliar с питоном и лямбда, не могли бы вы объяснить немного, что это делает? 'lambda m: threeLetterDict [m.group (0)]' большое спасибо! – Arch1tect

+0

@ Arch1tect: 'аргумент lambda: некоторое выражение' в значительной степени эквивалентно определению функции' def func (argument): возвращать некоторое выражение', а затем использовать его везде, где используется лямбда. То есть, это встроенная функция. Я надеюсь, что это имеет смысл: D – Ryan

+0

, но 're.sub' требует 3 аргумента правильно? вам не нужно проходить в 'p'? – Arch1tect

2

Вы, возможно, не нужно использовать суб здесь:

>>> p = re.compile('.{3}') 
>>> ''.join([threeLetterDict.get(i, i) for i in p.findall('abcdefghi')]) 
'foobarha' 

Просто альтернативное решение :).

3

Решение, которое позволяет избежать re полностью:

threeLetterDict={'abc': 'foo', 'def': 'bar', 'ghi': 'ha'} 

threes = map("".join, zip(*[iter('abcdefghi')]*3)) 

"".join(threeLetterDict[three] for three in threes) 
#>>> 'foobarha' 
Смежные вопросы