Seite 1 von 1

Einmal translate() statt mehrmals replace()

Verfasst: Samstag 24. November 2018, 10:10
von snafu
Habe mich mal intensiver mit str.translate() beschäftigt. Im Forum sehe ich dessen Nutzung recht selten, eigentlich fällt mir gerade gar kein Fall ein. Daher verliere ich nun ein paar Worte dazu.

Häufig hat man ja das Problem, dass mehrere Ersetzungen in Texten gemacht werden müssen. Da replace() immer nur eine Art von Ersetzung vornehmen kann (alle X durch Y), behilft man sich mit einer Aneinanderreihung von replace()-Aufrufen. Sagen wir mal, es sollen alle "X", "Y" und "Z" gelöscht werden. Das sähe mit replace() dann so aus:

Code: Alles auswählen

text = 'fhgfdhgXghsgkhXYsgskgZZZhsfgfgYYshfsZXZkfghXYZfhg'
clean_text = text.replace('X', '').replace('Y', '').replace('Z', '')
Unschön zu schreiben und auch mit ungünstiger Laufzeit, da jeder replace()-Aufruf wieder den kompletten Text durchlaufen muss.

Hier kommt nun translate() ins Spiel: Es nimmt für die Übersetzung ein Mapping (z.B. Wörterbuch). Wichtig ist, dass die Schlüssel Ordinals sein müssen, also der "Zahlwert" eines Zeichens. Die Werte können ebenfalls Ordinals sein oder normaler Text (wie bei replace()) oder None, wenn das Zeichen gelöscht werden soll. Hier also obiges Beispiel mit translate():

Code: Alles auswählen

text = 'fhgfdhgXghsgkhXYsgskgZZZhsfgfgYYshfsZXZkfghXYZfhg'
table = dict.fromkeys(map(ord, 'XYZ'))
clean_text = text.translate(table)
translate() geht hierbei in einem Rutsch die infrage kommenden Ersetzungen durch. Ein mehrfaches Durchlaufen des Textes wird also vermieden.

Zugegeben, der Aufbau der Übersetzungstabelle wirkt etwas lowlevel, aber das lässt sich natürlich in eine Funktion auslagern, wenn man möchte.

Re: Einmal translate() statt mehrmals replace()

Verfasst: Samstag 24. November 2018, 10:31
von ThomasL
Gut zu wissen, Danke.

Re: Einmal translate() statt mehrmals replace()

Verfasst: Samstag 24. November 2018, 10:43
von snafu
Und wenn einem das mit dem Ordinals mappen zu nervig ist, dann kann man auch zu maketrans() greifen. Obige Übersetzungstabelle erhält man so:

Code: Alles auswählen

table = str.maketrans(dict.fromkeys('XYZ'))
Sicherlich möchte man nicht nur Zeichen löschen, sondern auch ersetzen. Hier finde ich maketrans() auf jeden Fall einfacher in der Handhabung. Ein Beispiel:

Code: Alles auswählen

text = 'gsgfgsShhgrgrSgrhgHsgrghrHsgrshkkEkkbbSuubklkbHkbuu'
table = str.maketrans({'S': 'Spam', 'H': 'Ham', 'E': 'Eggs'})
spammed_text = text.translate(table)