mehrere replace Befehle hintereinander:

Wenn du dir nicht sicher bist, in welchem der anderen Foren du die Frage stellen sollst, dann bist du hier im Forum für allgemeine Fragen sicher richtig.
Antworten
Rufus
User
Beiträge: 6
Registriert: Donnerstag 22. Oktober 2020, 15:08
Wohnort: Bergisches Land

Hallo,
ich bin gerade Python Anfänger und habe eine Frage zu .replace auf die ich sonst nirgendwo eine Antwort finde.
Wenn ich einen string habe wie:

Code: Alles auswählen

var = 'abc'
und ich möchte das a mit h , das b mit i und das c mit j ersetzen, würde ich das machen :

Code: Alles auswählen

var = 'abc'
var = var.replace ('a','h')
var = var.replace ('b','i')
var = var.replace ('c','j')
print(var)
Gibt es da eine Möglickeit die ganzen replace-Schritte kürzer zu formulieren? :?
Schon mal Danke für Tips.
Rufus :D
Benutzeravatar
__blackjack__
User
Beiträge: 14002
Registriert: Samstag 2. Juni 2018, 10:21
Wohnort: 127.0.0.1
Kontaktdaten:

@Rufus: Schau Dir mal die `translate()`-Methode an.
“The best book on programming for the layman is »Alice in Wonderland«; but that's because it's the best book on anything for the layman.” — Alan J. Perlis
Benutzeravatar
snafu
User
Beiträge: 6850
Registriert: Donnerstag 21. Februar 2008, 17:31
Wohnort: Gelsenkirchen

Wobei mehrere replace()-Aufrufe jetzt echt nicht langsam sind. Die kann man ja auch in einer Schleife aufrufen:

Code: Alles auswählen

replacements = {"a": "h", "b": "i", "c": "j"}
for needle, repl in replacements.items():
    string = string.replace(needle, repl)
Hat im Gegensatz zu translate() auch den Vorteil, dass die gesuchte Nadel länger als ein Zeichen sein darf.
Rufus
User
Beiträge: 6
Registriert: Donnerstag 22. Oktober 2020, 15:08
Wohnort: Bergisches Land

__blackjack__ hat geschrieben: Donnerstag 22. Oktober 2020, 17:21 @Rufus: Schau Dir mal die `translate()`-Methode an.


Bei dictionarys bin ich noch nicht angekommen aber danke schonmal.
Rufus :D
Rufus
User
Beiträge: 6
Registriert: Donnerstag 22. Oktober 2020, 15:08
Wohnort: Bergisches Land

@snafu Auch danke.
Rufus :D
Benutzeravatar
__blackjack__
User
Beiträge: 14002
Registriert: Samstag 2. Juni 2018, 10:21
Wohnort: 127.0.0.1
Kontaktdaten:

Wobei man bei snafus Beispiel noch anmerken sollte das Python erst ab 3.7 garantiert, dass die Reihenfolge der Ersetzungen auch der Reihenfolge entspricht die da in dem Wörterbuchliteral steht. Das macht beim gegebenen Beispiel keinen Unterschied, aber es kann auch Ersetzungen geben bei denen die Reihenfolge in der ersetzt wird, eine Rolle spielt.
“The best book on programming for the layman is »Alice in Wonderland«; but that's because it's the best book on anything for the layman.” — Alan J. Perlis
Benutzeravatar
snafu
User
Beiträge: 6850
Registriert: Donnerstag 21. Februar 2008, 17:31
Wohnort: Gelsenkirchen

Beim "Standard-Interpreter" CPython bleibt die festgelegte Reihenfolge sogar schon ab Version 3.6 erhalten und PyPy (wohl die meistgenutzte Alternative) hat es schon Anfang 2015 eingeführt (https://morepypy.blogspot.com/2015/01/f ... -more.html). Wie dem auch sei: Wer aus Gründen noch ältere Python-Versionen unterstützen muss oder sich nicht sicher ist, kann die Ersetzungen auch als Liste schreiben in einer Form wie dieser:

Code: Alles auswählen

replacements = [("a", "h"), ("b", "i"), ("c", "j")]
for needle, repl in replacements:
    # ...
...oder natürlich auf collections.OrderedDict zurückgreifen.
Benutzeravatar
DeaD_EyE
User
Beiträge: 1224
Registriert: Sonntag 19. September 2010, 13:45
Wohnort: Hagen
Kontaktdaten:

Es gibt keine Python-Version mehr, die noch unterstützt wird und die Reihenfolge der Keys in den dicts nicht behält.
Python 2.7 und 3.5 sind EOL.

Ich finde es gut, dass die Unterstützung von Python 3.5 endlich beendet ist.
So kann man annehmen, dass mindestens überall Python 3.6 installiert ist.
Um sicherzustellen, dass das so ist, f-strings verwenden!

Bei Python 3.5 lässt sich das Programm dann aufgrund eines Syntaxfehlers nicht ausführen.
sourceserver.info - sourceserver.info/wiki/ - ausgestorbener Support für HL2-Server
Benutzeravatar
__blackjack__
User
Beiträge: 14002
Registriert: Samstag 2. Juni 2018, 10:21
Wohnort: 127.0.0.1
Kontaktdaten:

Es gibt noch Python 3.6 da ist das nicht garantiert.
“The best book on programming for the layman is »Alice in Wonderland«; but that's because it's the best book on anything for the layman.” — Alan J. Perlis
Rufus
User
Beiträge: 6
Registriert: Donnerstag 22. Oktober 2020, 15:08
Wohnort: Bergisches Land

__blackjack__ hat geschrieben: Freitag 23. Oktober 2020, 15:48 Es gibt noch Python 3.6 da ist das nicht garantiert.
Ich habe sowieso schon die

Code: Alles auswählen

replacements = {"a": "h", "b": "i", "c": "j"}
for needle, repl in replacements.items():
    string = string.replace(needle, repl)
Methode angewendet und das hat mir viel gebracht. Also danke nochmal.
Ich hab übrigens Python 3.9
Rufus :D
Benutzeravatar
DeaD_EyE
User
Beiträge: 1224
Registriert: Sonntag 19. September 2010, 13:45
Wohnort: Hagen
Kontaktdaten:

__blackjack__ hat geschrieben: Freitag 23. Oktober 2020, 15:48 Es gibt noch Python 3.6 da ist das nicht garantiert.
Stimmt, ist kein Sprachfeature, sondern ein Detail der Implementierung, dass man dann seit Python 3.7 in der Sprache übernommen hat.
Was spricht dagegen dieses Implementierungsdetail auszunutzen, wo man sogar weiß, dass das nicht mehr entfernt werden wird und in neueren Versionen der Sprache der Standard ist?

Wer andere Implementierungen von Python verwendet, muss sich informieren, welche Features unterstützt werden und welche nicht.
sourceserver.info - sourceserver.info/wiki/ - ausgestorbener Support für HL2-Server
Jankie
User
Beiträge: 592
Registriert: Mittwoch 26. September 2018, 14:06

Zur Vervollständigung hier noch mit der translate Methode die __blackjack__ erwähnt hatte.

Code: Alles auswählen

with open("test.txt", "r", encoding='UTF-8') as input_file:
    with open("test_output.txt", "w", encoding='UTF-8') as output_file:
        output_file.writelines([row.lower().translate(str.maketrans("ioabt", "10487")) for row in input_file.readlines()])
Sirius3
User
Beiträge: 18253
Registriert: Sonntag 21. Oktober 2012, 17:20

@Jankie: einfacher geht es mit write und read. Dann spart man sich die Listcomprehension.
readlines wird eigenrlich nie gebraucht. Man iteriert normalerweise direkt über das Fileobjekt. Und falls man doch alle Zeilen in einer Liste braucht, nehme ich list(inputfile).
Die Listcomprehension ist unnötig, da würde man einem Generatorausdruck an writelines übergeben.
Benutzeravatar
__blackjack__
User
Beiträge: 14002
Registriert: Samstag 2. Juni 2018, 10:21
Wohnort: 127.0.0.1
Kontaktdaten:

Das `str.maketrans("ioabt", "10487")` würde ich da raus ziehen, denn das muss ja nur einmal berechnet werden, nicht für jede Zeile erneut. Und wo kommt das `lower()` her?
“The best book on programming for the layman is »Alice in Wonderland«; but that's because it's the best book on anything for the layman.” — Alan J. Perlis
Jankie
User
Beiträge: 592
Registriert: Mittwoch 26. September 2018, 14:06

Habe es noch mal angepasst.

Code: Alles auswählen

with open("test.txt", "r", encoding='UTF-8') as input_file:
    with open("test_output.txt", "w", encoding='UTF-8') as output_file:
        output_file.write(input_file.read().translate(str.maketrans("abc", "hij")))
Benutzeravatar
sparrow
User
Beiträge: 4528
Registriert: Freitag 17. April 2009, 10:28

Eine Einrückungsebene kann man sich sparen, wenn man die with-Statements zusammenfasst.
Sollte ab 3.9 gehen (vorher mit \ und ohne Klammern):

Code: Alles auswählen

with (
    open("test.txt", "r", encoding='UTF-8') as input_file,
    open("test_output.txt", "w", encoding='UTF-8') as output_file
):
    output_file.write(input_file.read().translate(str.maketrans("abc", "hij")
Antworten