2009-04-18 8 views
22

¿Existe una manera mucho más corta de escribir el siguiente código?Una lista de reemplazos de cadena en Python

my_string = my_string.replace('A', '1') 
my_string = my_string.replace('B', '2') 
my_string = my_string.replace('C', '3') 
my_string = my_string.replace('D', '4') 
my_string = my_string.replace('E', '5') 

Tenga en cuenta que no necesito esos valores exactos sustituido; Simplemente estoy buscando una manera de convertir más de 5 líneas en menos de 5

Respuesta

44

parece una buena oportunidad de utilizar un bucle:

mapping = { 'A':'1', 'B':'2', 'C':'3', 'D':'4', 'E':'5'} 
for k, v in mapping.iteritems(): 
    my_string = my_string.replace(k, v) 

Un enfoque más rápido si no le importa los paréntesis serían:

mapping = [ ('A', '1'), ('B', '2'), ('C', '3'), ('D', '4'), ('E', '5') ] 
for k, v in mapping: 
    my_string = my_string.replace(k, v) 
+1

Es extraño; así es como lo escribiría, porque el problema es hacer un mapeo de un personaje a otro. Pero realmente, no estás usando el dict como dict; lo estás usando como una lista de tuplas. Entonces, ¿por qué no escribir una lista de tuplas en primer lugar? –

+0

Ciertamente, una lista de tuplas también funcionaría (y sería más rápida). Editaré la respuesta para incluir esa opción. –

+2

¿Qué pasa si usted tiene esta asignación {'A': '1', '1': 'A'}, probablemente el resultado no será el mismo que el esperado – muni764

6
replaceDict = {'A':'1','B':'2','C':'3','D':'4','E':'5'}  
for key, replacement in replaceDict.items(): 
    my_string = my_string.replace(key, replacement)
15

también mirar en str.translate(). Reemplaza los caracteres de acuerdo con una asignación que proporciones para cadenas Unicode, o de lo contrario se debe decir con qué reemplazar cada carácter de chr (0) a chr (255) con.

35

Usted puede utilizar fácilmente string.maketrans() para crear la cadena de mapeo para pasar a str.translate():

import string 
trans = string.maketrans("ABCDE","12345") 
my_string = my_string.translate(trans) 
+2

esto es bueno, pero no funciona en el caso de patrones de caracteres múltiples o reemplazos –

+0

Correcto. Supuse a partir de la pregunta que era un reemplazo basado en el carácter. –

+0

me ahorra una pregunta, thx – ohho

10

Si desea obtener la respuesta equivocada, poco a poco, a continuación, utilizar String.Replace en un bucle (A pesar de que no funciona en este caso de ninguna superposición entre los patrones y los reemplazos.)

Para el caso general con posibles solapamientos o una cadena de asunto largo, el uso re.sub:

import re 

def multisub(subs, subject): 
    "Simultaneously perform all substitutions on the subject string." 
    pattern = '|'.join('(%s)' % re.escape(p) for p, s in subs) 
    substs = [s for p, s in subs] 
    replace = lambda m: substs[m.lastindex - 1] 
    return re.sub(pattern, replace, subject) 

>>> multisub([('hi', 'bye'), ('bye', 'hi')], 'hi and bye') 
'bye and hi' 

para el especial caso de patrones de 1 carácter y reemplazos de 1 o 0 caracteres, use string.maketrans.

+0

+1 en el enfoque de usar re.sub, -1 por decir que 'string.replace' da la respuesta incorrecta, ya que no está claro exactamente qué * debería * suceder para la superposición de coincidencias. Tan neto 0 :) –

+1

str.replace puede dar una respuesta posiblemente incorrecta. Para las soluciones basadas en diccionarios, considere la cadena "wow" y la tabla de traducción {'w': 'foo', 'o': 'bar'}. Dependiendo del orden en que se repita el dict, puede terminar con diferentes resultados: "fbarbarbarbarbarbar" o "foobarfoo". Una función que da salida diferente para una entrada igual se puede decir que está rota. – Miles

+0

Millas, sí, ese es el tipo de problema que quise decir.También podría encontrarse con solapamientos en las teclas, como 'hola' e 'infierno'. –

1

Una forma de hacerlo es con una matriz asociada (un diccionario). Aquí hay un ejemplo de los reemplazos que uso cuando preparo un archivo para su implementación en LaTeX usando expresiones regulares.

import re 
    def escapeTexString(string): # Returns TeX-friendly string 
    rep = { # define desired replacements in this dictionary (mapping) 
     '&': '\\&', 
     '%': '\\%', 
     '#': '\\#', 
     '_': '\\_', 
     '{': '\\{', # REGEX Special 
     '}': '\\}', # REGEX Special 
     '~': '\\char"007E{}', # LaTeX Special 
     '$': '\\$', # REGEX Special 
     '\\': '\\char"005C{}', # REGEX/LaTeX Special 
     '^': '\\char"005E{}', # REGEX/LaTeX Special 
     '"': '\\char"FF02{}' 
     } 
    # use these two lines to do the replacement (could be shortened to one line) 
    pattern = re.compile("|".join(map(re.escape,rep.keys()))) # Create single pattern object (key to simultaneous replacement) 
    new_string = pattern.sub(lambda match: rep[match.group(0)], string) 
    return new_string 
Cuestiones relacionadas