Скажем, у меня есть строка, "ab"
Я хочу заменить "a" на "b" и "b" на "a" одним махом.
Итак, конечная строка должна указывать "ba", а не "aa" или "bb" и не использовать более одной строки. Это выполнимо?
Скажем, у меня есть строка, "ab"
Я хочу заменить "a" на "b" и "b" на "a" одним махом.
Итак, конечная строка должна указывать "ba", а не "aa" или "bb" и не использовать более одной строки. Это выполнимо?
Когда вам нужно обменивать переменные, скажем, x и y, общий шаблон - ввести временную переменную t, которая поможет с заменой: t = x; x = y; y = t
.
Тот же шаблон можно также использовать со строками:
>>> # swap a with b
>>> 'obama'.replace('a', '%temp%').replace('b', 'a').replace('%temp%', 'b')
'oabmb'
Эта техника не нова. Он описан в PEP 378 как способ преобразования между десятичными разделителями между американским и европейским стилем и тысячами разделителей (например, от 1,234,567.89
до 1.234.567,89
. Гвидо одобрил это как разумную технику.
import string
"abaababb".translate(string.maketrans("ab", "ba"))
# result: 'babbabaa'
Обратите внимание, что это работает только для односимвольных подстановок.
Для более длинных подстрок или подстановок это немного сложно, но может работать:
import re
def replace_all(repls, str):
# return re.sub('|'.join(repls.keys()), lambda k: repls[k.group(0)], str)
return re.sub('|'.join(re.escape(key) for key in repls.keys()),
lambda k: repls[k.group(0)], str)
text = "i like apples, but pears scare me"
print replace_all({"apple": "pear", "pear": "apple"}, text)
К сожалению это не будет работать, если вы включите специальные символы регулярных выражений, вы не можете использовать регулярные выражения таким образом: (
(Спасибо @TimPietzcker)
Если вы в порядке с двумя строками, это более элегантно.
d={'a':'b','b':'a'}
''.join(d[s] for s in "abaababbd" if s in d.keys())
Ваш пример немного абстрактный, но в прошлом я использовал этот рецепт, который строит регулярное выражение для однопроходного множественная замена. Вот моя измененная версия:
import re
def multiple_replace(dict, text):
regex = re.compile("|".join(map(re.escape, dict.keys())))
return regex.sub(lambda mo: dict[mo.group(0)], text)
Обратите внимание, что клавиши (searchstrings) re.escaped.
В вашем случае это будет:
from utils import multiple_replace
print multiple_replace({
"a": "b",
"b": "a"
}, "ab")
UPDATE:
В настоящее время это в основном то же самое, что ответ Амадана
>>> import re
>>> re.sub('.', lambda m: {'a':'b', 'b':'a'}.get(m.group(), m.group()), 'abc')
'bac'
the_string="ab"
new_string=""
for x in range(len(the_string)):
if the_string[x]=='a':
new_string+='b'
continue
if the_string[x]=='b':
new_string+='a'
continue
new_string+=the_string[x]
the_string=new_string
print the_string