¿Cómo reemplazar dos cosas a la vez en una cadena?

Digamos que tengo una cadena, "ab" .

Quiero reemplazar "a" con "b" y "b" con "a" de una sola vez.

Así que al final, la cadena debe ser "ba" y no "aa" o "bb" y no usar más de una línea. ¿Es esto factible?

Cuando necesite cambiar las variables, digamos x e y , un patrón común es introducir una variable temporal t para ayudar con el intercambio: t = x; x = y; y = t t = x; x = y; y = t t = x; x = y; y = t .

El mismo patrón también se puede usar con cuerdas:

 >>> # swap a with b >>> 'obama'.replace('a', '%temp%').replace('b', 'a').replace('%temp%', 'b') 'oabmb' 

Esta técnica no es nueva. Se describe en PEP 378 como una forma de conversión entre separadores decimales de estilo estadounidense y europeo y separadores de miles (por ejemplo, de 1,234,567.89 a 1,234,567.89 . Guido lo ha considerado como una técnica razonable.

 import string "abaababb".translate(string.maketrans("ab", "ba")) # result: 'babbabaa' 

Tenga en cuenta que esto solo funciona para las sustituciones de un carácter.

Para subcadenas más largas o sustituciones, esto es un poco complejo, pero podría funcionar:

 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) 

Desafortunadamente, esto no funcionará si incluye caracteres especiales de expresión regular que no puede usar de esta manera 🙁

(Gracias @TimPietzcker)

Si estás de acuerdo con dos líneas, esto es más elegante.

 d={'a':'b','b':'a'} ''.join(d[s] for s in "abaababbd" if s in d.keys()) 

Su ejemplo es un poco abstracto, pero en el pasado he usado esta receta que construye una expresión regular para realizar reemplazos múltiples de una sola pasada. Aquí está mi versión ajustada de la misma:

 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) 

Tenga en cuenta que las claves (cadenas de búsqueda) son re.escaped.

En tu caso sería:

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

ACTUALIZAR:

Por ahora esto es básicamente lo mismo que la respuesta de Amadan.

 >>> 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