Dis que j'ai une ficelle, "ab"
Je veux remplacer "a" par "b" et "b" par "a" d'un coup.
Ainsi, la chaîne de fin devrait indiquer "ba" et non "aa" ou "bb" et ne pas utiliser plus d'une ligne. Est-ce faisable?
Si vous devez échanger des variables, dites x et y , un modèle courant consiste à introduire une variable temporaire t pour faciliter l’échange: t = x; x = y; y = t
.
Le même motif peut également être utilisé avec des chaînes:
>>> # swap a with b
>>> 'obama'.replace('a', '%temp%').replace('b', 'a').replace('%temp%', 'b')
'oabmb'
Cette technique n'est pas nouvelle. Il est décrit dans le document PEP 378 comme un moyen de convertir des séparateurs décimaux de style américain et européen en milliers (par exemple de 1,234,567.89
à 1.234.567,89
. Guido a approuvé cette technique comme étant raisonnable.
import string
"abaababb".translate(string.maketrans("ab", "ba"))
# result: 'babbabaa'
Notez que cela ne fonctionne que pour les substitutions d'un caractère.
Pour des sous-chaînes ou des substitutions plus longues, ceci est un peu complexe, mais pourrait fonctionner
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)
Malheureusement cela ne fonctionnera pas si vous incluez des caractères spéciaux regexp vous ne pouvez pas utiliser les expressions rationnelles de cette façon :(
(Merci @ Timpietzcker)
Si vous êtes d'accord avec deux lignes, c'est plus élégant.
d={'a':'b','b':'a'}
''.join(d[s] for s in "abaababbd" if s in d.keys())
Votre exemple est un peu abstrait, mais j’avais utilisé jadis cette recette pour créer une expression régulière permettant de remplacer plusieurs passes par passe. Voici ma version modifiée de celui-ci:
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)
Notez que les clés (searchstrings) sont rééchappées.
Dans votre cas ce serait:
from utils import multiple_replace
print multiple_replace({
"a": "b",
"b": "a"
}, "ab")
METTRE À JOUR:
A présent, ceci est fondamentalement le même que réponse d'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