@Tomes: In `ersetzten()` ist ein "t" zu viel und die Funktion sollte nur aufgerufen werden wenn das als Programm ausgeführt wird, aber nicht wenn es als Modul in einem anderen Modul oder in einer Python-Shell importiert wird.
``global`` hat in einem sauberen Programm nichts zu suchen. Vergiss das Schlüsselwort am besten sofort wieder. Es macht hier auch überhaupt gar keinen Sinn. Zudem vermute ich Du dachtest `s` wäre auch ``global``‽ Ist es nicht, weil das Semikolon Anweisungen trennt.
Und `s` einfach so als Anweisung hat keinen Effekt. Da wird der Wert von `s` ermittelt, und dann wird damit einfach nichts gemacht und mit der nächsten Anweisung im Programm fortgefahren.
`s` wird zweimal an eine jeweils neue leere Liste gebunden. Einmal reicht.
`mater_liste` wird definiert aber nirgends verwendet.
`line` wird vor der Schleife ebenfalls an eine leere Liste gebunden, aber auch die wird nirgends verwendet, und zusätzlich werden *in* der Schleife dann Zeichenketten an den Namen `line` gebunden. Man sollte im gleichen Namensraum nur Objekte vom gleichen (Duck-)Typ an einen Namen binden. Sonst ist irgendwann der Leser verwirrt und versteht nicht mehr was da passiert.
Namen sollte keine kryptischen Abkürzungen enthalten, oder gar nur daraus bestehen. Einbuchstabige Namen sind selten gute Namen. `i` und `j` für einen Laufindex oder `x`, `y`, und `z` für Koordinaten geht, `s` für eine Liste mit Zeilen oder `y` für das Ergebnis eines Tests sind unverständlich.
`y` braucht man auch überhaupt nicht. Das wird ja nur einmal in der nächsten Zeile als ``if``-Bedingung verwendet. Da kann man auch gleich das `startswith()` einsetzen.
Man macht keine Vergleiche mit literalen Wahrheitswerten. Bei dem Vergleich kommt doch nur wieder ein Wahrheitswert bei heraus. Entweder der, den man sowieso schon hatte; dann kann man den auch gleich nehmen. Oder das Gegenteil davon; dafür gibt es ``not``.
Code: Alles auswählen
y = line.startswith("PETER")
if y == True:
...
# =>
if line.startswith("PETER"):
...
Dann wären wir für das einlesen und verändern der Daten bei diesem Code:
Code: Alles auswählen
lines = []
for line in file:
if line.startswith("PETER"):
line = f"{line[:8]} TEST{line[16:]}"
lines.append(line)
Oder als „list comprehension“:
Code: Alles auswählen
lines = [
(
f"{line[:8]} TEST{line[16:]}"
if line.starswith("PETER")
else line
)
for line in file
]
`s` beziehungsweise `lines` enthält bereits Zeichenketten. Da mit `map()` noch mal `str()` auf jede Zeichenkette anzuwenden macht keinen Sinn.
Ja, man kann die ganzen Zeilen per `join()` vor dem schreiben zu einer grossen Zeichenkette zusammensetzen. Man könnte aber auch einfach die `writelines()`-Methode mit den Zeilen aufrufen. Womit das schreiben der Datei dann so aussieht:
Code: Alles auswählen
with open("datei_neu.txt", "w", encoding="cp1252") as file:
file.writelines(lines)
Jetzt könnte man sich auch noch überlegen ob überhaupt mehr als eine Zeile von der Eingangsdatei zur gleichen Zeit im Speicher sein muss. Deswegen macht die „list comprehension“ beim Lesen Sinn, auch wenn die das gleiche wie die Schleife macht: Man kann da trivial einen Generatorausdruck machen, den man direkt an `writelines()` übergeben kann, womit wir dann bei folgendem Programm wären:
Code: Alles auswählen
#!/usr/bin/env python3
ENCODING = "cp1252"
def ersetzen():
with open("datei.txt", "r", encoding=ENCODING) as lines:
with open("datei_neu.txt", "w", encoding=ENCODING) as file:
file.writelines(
(
f"{line[:8]} TEST{line[16:]}"
if line.starswith("PETER")
else line
)
for line in lines
)
if __name__ == "__main__":
ersetzen()