2011-12-31 16 views

Respuesta

41

Cuando tenga que cambiar las variables, digamos x y y, un commo n patrón es introducir una variable temporal t para ayudar con el intercambio: t = x; x = y; y = t.

El mismo patrón también se puede utilizar con cadenas:

>>> # 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 convertir separadores decimales de estilo americano y europeo y separadores de miles (por ejemplo, de 1,234,567.89 a 1.234.567,89. Guido ha respaldado esto como una técnica razonable.

+2

¿Están todos de acuerdo con el hecho de que cualquier cadena que contenga% temp% se alterará incorrectamente? –

+0

Tiendo a hacer esto con algo ridículo como - - \ _ (descriptor) \ _-. Wordy pero las posibilidades de colisión son * escasas. – wom

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

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

Para subseries más largos 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 se incluyen todos los caracteres especiales de expresiones regulares no se pueden utilizar las expresiones regulares de esta manera :(

(Gracias @TimPietzcker)

+0

NVM, tengo. hazlo para más de un personaje? Digamos si quiero cambiar a "anuncio"? – WhatsInAName

+0

Puedes reemplazar cualquier número de caracteres individuales con algunos otros caracteres individuales. Si quieres reemplazar cadenas (por ejemplo, '" apple "' con '" delicioso "' pero '" pera "' con '" payaso "'), esto no sería apropiado. – Amadan

+0

Ahí va ... – Amadan

0
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 
+1

OP: "y no use más de una línea" – Amadan

+2

Me lo perdí, realmente debería dejar de publicar a las 10 pm ... –

+2

Bueno, creo que hice trampa también, con la 'importación' ...: P – Amadan

7

Si estás bien 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()) 
+4

' '' .join (d [s] if s en d else s para s en "abaababbd") ' – wim

+0

@ wim la respuesta es la mejor aquí. – twasbrillig

+0

''' .join (d.get (s, s) para s en" abaababbd ")' –

2

Su ejemplo es un poco abstracto, pero en el pasado he utilizado this recipe que construye una expresión regular para hacer múltiples de un solo paso sustituir. Aquí está mi versión modificada 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 teclas (searchstrings) se re.escaped.

En su caso sería:

from utils import multiple_replace 

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

ACTUALIZACIÓN:

Por ahora esto es básicamente el mismo que Amadan's answer

1
>>> import re 
>>> re.sub('.', lambda m: {'a':'b', 'b':'a'}.get(m.group(), m.group()), 'abc') 
'bac' 
Cuestiones relacionadas