2009-04-18 5 views
22

Czy istnieje o wiele krótszy sposób napisania następującego kodu?Lista elementów zastępujących łańcuchy znaków w języku 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') 

Należy pamiętać, że nie potrzebuję tych dokładnych wartości zastąpionych; Ja po prostu szukasz sposobu, aby włączyć 5+ linie do mniej niż 5

Odpowiedz

44

Wygląda na to dobra okazja, aby wykorzystać pętlę:

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

Szybszy podejście, jeśli nie przeszkadza nawiasy byłoby:

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

To dziwne; tak to napisałem, ponieważ problem polega na mapowaniu z jednej postaci na drugą. Ale tak naprawdę, nie używasz dyktatury jako dyktatury; używasz go jako listy krotek. Dlaczego więc nie napisać listy krotek? –

+0

Z pewnością lista krotek również zadziała (i będzie szybsza). Będę edytować odpowiedź, aby uwzględnić tę opcję. –

+2

Co jeśli będziesz miał to mapowanie {'A': '1', '1': "A"} prawdopodobnie wynik nie będzie taki sam jak oczekiwano – 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

spojrzeć także na str.translate(). Zastępuje znaki zgodnie z odwzorowaniem, które podajesz na ciągi znaków Unicode, lub w inny sposób musi być powiedziane, co zastąpić każdy znak od chr (0) do chr (255) z.

35

można łatwo używać string.maketrans(), aby utworzyć łańcuch odwzorowania przejść do str.translate():

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

jest to miłe, ale nie działa w przypadku wzorów wielopiętrowych lub zamienników –

+0

Prawidłowo. Z pytania wynikało, że chodzi o zastąpienie oparte na znakach. –

+0

zapisuje mi pytanie, thx – ohho

10

Jeśli chcesz dostać złą odpowiedź, powoli, a następnie użyć string.replace w pętli. (Choć to nie działa w tym przypadku nie pokrywają się między wzorami i zamienników.)

W ogólnym przypadku z możliwych nakładania lub ciąg długi temat, stosowanie 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' 

do specjalnego w przypadku wzorców 1-znakowych i zamienników 1- lub 0-znakowych, użyj string.maketrans.

+0

+1 w podejściu do używania re.sub, -1 dla stwierdzenia, że ​​'string.replace' podaje błędną odpowiedź, ponieważ nie jest jasne, co dokładnie * powinno * wydarzyć się w przypadku nakładających się dopasowań. Tak netto 0 :) –

+1

str.replace może dać prawdopodobnie niewłaściwą odpowiedź. W przypadku rozwiązań opartych na słownikach, weź pod uwagę ciąg "wow" i tabelę tłumaczeń {'w': "foo", "o": "bar"}. W zależności od kolejności iteracji dyktowania można uzyskać różne wyniki: "fbarbarbarfbarbar" lub "foobarfoo". Funkcja, która daje różne dane wyjściowe dla równego wejścia, jest prawdopodobnie zepsuta. – Miles

+0

Mile, tak, to był problem, który miałem na myśli.Można również spotkać się z zachowaniem samych kluczy, takich jak "cześć" i "piekło". –

1

Jednym ze sposobów, w jaki to robię, jest powiązana tablica (słownik). Oto przykład zamienników, których używam podczas pobierania pliku gotowego do wdrożenia w LaTeX przy użyciu wyrażeń regularnych.

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