Как заменить две вещи одновременно в строке? - PullRequest
31 голосов
/ 31 декабря 2011

Скажите, у меня есть строка, "ab".

Я хочу заменить "a" на "b" и "b" на "a" одним махом.

Таким образом, в конце строка должна быть "ba", а не "aa" или "bb" и не использовать более одной строки. Это выполнимо?

Ответы [ 6 ]

42 голосов
/ 31 декабря 2011

Когда вам нужно поменять местами переменные, скажем, 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. Гвидо одобрил это как разумную технику.

20 голосов
/ 31 декабря 2011
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)

7 голосов
/ 31 декабря 2011

Если вы в порядке с двумя линиями, это более элегантно.

d={'a':'b','b':'a'}
''.join(d[s] for s in "abaababbd" if s in d.keys())
2 голосов
/ 31 декабря 2011

Ваш пример немного абстрактен, но в прошлом я использовал этот рецепт , который создает регулярное выражение для однократной многократной замены. Вот моя измененная версия:

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) 

Обратите внимание, что ключи (строки поиска) повторно сохранены.

В вашем случае это будет:

from utils import multiple_replace

print multiple_replace({
    "a": "b",
    "b": "a"
}, "ab") 

UPDATE:

К настоящему времени это в основном то же самое, что и Ответ Амадана

1 голос
/ 31 декабря 2011
>>> import re
>>> re.sub('.', lambda m: {'a':'b', 'b':'a'}.get(m.group(), m.group()), 'abc')
'bac'
0 голосов
/ 31 декабря 2011
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
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...