Замены с элементами из списка с re.sub?

Каков наилучший способ выполнения подстановок с re.sub учетом списка? Например:

 import re some_text = 'xxxxxxx@yyyyyyyyy@zzzzzzzzz@' substitutions = ['ONE', 'TWO', 'THREE'] x = re.sub('@', lambda i: i[0] substitutions.pop(0), some_text) # this doesn't actually work 

Желаемый результат:

 some_text = 'xxxxxxxONEyyyyyyyyyTWOzzzzzzzzzTHREE' 

У вас просто синтаксическая ошибка в вашей лямбде:

 >>> substitutions = ['ONE', 'TWO', 'THREE'] >>> re.sub('@', lambda _: substitutions.pop(0), some_text) 'xxxxxxxONEyyyyyyyyyTWOzzzzzzzzzTHREE' 

Если вы не хотите изменять список, вы можете обернуть его итерабельным.

 >>> substitutions = ['ONE', 'TWO', 'THREE'] >>> subs = iter(substitutions) >>> re.sub('@', lambda _: next(subs), some_text) 'xxxxxxxONEyyyyyyyyyTWOzzzzzzzzzTHREE' 

Один из способов (вероятно, лучший, я действительно не знаю Python) заключается в компиляции регулярного выражения, а затем использовать этот sub :

 import re some_text = 'xxxxxxx@yyyyyyyyy@zzzzzzzzz@' substitutions = ['ONE', 'TWO', 'THREE'] pattern = re.compile('@') x = pattern.sub(lambda i: substitutions.pop(0), some_text) 

Вот демо.

Код почти правильный, ему нужна небольшая коррекция синтаксической ошибки:

 import re some_text = 'xxxxxxx@yyyyyyyyy@zzzzzzzzz@' substitutions = ['ONE', 'TWO', 'THREE'] x = re.sub('@', lambda i: substitutions.pop(0), some_text) # the error was in the lambda function