Also lerne ich Python. Ich gehe die Lektionen durch und bin auf ein Problem gestoßen, bei dem ich sehr viele target.write()
zu einer einzigen zusammenfassen musste write()
, während ich "\n"
zwischen jeder Benutzereingabevariable (das Objekt von write()
) eine hatte.
Ich hatte die Idee dass:
nl = "\n"
lines = line1, nl, line2, nl, line3, nl
textdoc.writelines(lines)
Wenn ich versuche zu tun:
textdoc.write(lines)
Ich bekomme eine Fehlermeldung. Aber wenn ich tippe:
textdoc.write(line1 + "\n" + line2 + ....)
Dann funktioniert es gut. Warum kann ich keinen String für eine neue Zeile verwenden, write()
aber ich kann ihn verwenden writelines()
?
Python 2.7 Als ich bei Google nach den meisten Ressourcen gesucht habe, die ich gefunden habe, bin ich immer noch ein Laie.
python
string
file-io
python-2.x
AbeLinkon
quelle
quelle
lines
ist in Ihrem Beispiel keine Zeichenfolge. Es ist ein Tupel, das aus sechs Saiten besteht.Antworten:
writelines
erwartet eine Iteration von Stringswrite
erwartet eine einzelne Zeichenfolge.line1 + "\n" + line2
führt diese Zeichenfolgen zu einer einzelnen Zeichenfolge zusammen, bevor sie an übergeben werdenwrite
.Beachten Sie, dass Sie möglicherweise verwenden möchten, wenn Sie viele Zeilen haben
"\n".join(list_of_lines)
.quelle
writelines
erwartet eine iterable. Sie können eine Liste, ein Tupel oder einen Generator verwenden.write
anstelle von verwenden,writelines
wenn Sie viele Zeilen haben? Writelines könnten eine bessere Leistung erzielen, da sie keine temporäre verkettete Zeichenfolge erstellen müssen, sondern nur über die Zeilen iterieren.Warum kann ich in write () keine Zeichenfolge für eine neue Zeile verwenden, aber in writelines ()?
Die Idee ist folgende: Wenn Sie eine einzelne Zeichenfolge schreiben möchten, können Sie dies tun
write()
. Wenn Sie eine Folge von Zeichenfolgen haben, können Sie diese alle mit schreibenwritelines()
.write(arg)
erwartet einen String als Argument und schreibt ihn in die Datei. Wenn Sie eine Liste von Zeichenfolgen angeben, wird eine Ausnahme ausgelöst (zeigen Sie uns übrigens Fehler!).writelines(arg)
erwartet ein iterierbares Argument (ein iterierbares Objekt kann im allgemeinsten Sinne ein Tupel, eine Liste, eine Zeichenfolge oder ein Iterator sein). Es wird erwartet, dass jedes im Iterator enthaltene Element eine Zeichenfolge ist. Ein Tupel von Zeichenfolgen ist das, was Sie bereitgestellt haben, also haben die Dinge funktioniert.Die Art der Zeichenfolge (n) spielt für beide Funktionen keine Rolle, dh sie schreiben einfach in die Datei, was auch immer Sie ihnen zur Verfügung stellen. Der interessante Teil ist, dass
writelines()
keine Zeilenumbruchzeichen hinzugefügt werden, sodass der Methodenname tatsächlich ziemlich verwirrend sein kann. Es verhält sich tatsächlich wie eine imaginäre Methode namenswrite_all_of_these_strings(sequence)
.Was folgt, ist eine idiomatische Methode in Python, um eine Liste von Zeichenfolgen in eine Datei zu schreiben, während jede Zeichenfolge in einer eigenen Zeile bleibt:
Dadurch wird die Datei für Sie geschlossen. Das Konstrukt
'\n'.join(lines)
verkettet (verbindet) die Zeichenfolgen in der Listelines
und verwendet das Zeichen '\ n' als Klebstoff. Es ist effizienter als die Verwendung des+
Operators.Ausgehend von derselben
lines
Sequenz, endend mit derselben Ausgabe, aber mitwritelines()
:Dies verwendet einen Generatorausdruck und erstellt dynamisch Zeichenfolgen mit Zeilenumbruch.
writelines()
iteriert über diese Folge von Zeichenfolgen und schreibt jedes Element.Bearbeiten: Ein weiterer Punkt, den Sie beachten sollten:
write()
undreadlines()
existierte, bevorwritelines()
eingeführt wurde.writelines()
wurde später als Gegenstück zu eingeführtreadlines()
, so dass man den Dateiinhalt, der gerade gelesen wurde, leicht schreiben konnte überreadlines()
:Wirklich, das ist der Hauptgrund, warum
writelines
so ein verwirrender Name hat. Auch heute wollen wir diese Methode nicht mehr wirklich anwenden.readlines()
Liest die gesamte Datei in den Speicher Ihres Computers, bevorwritelines()
mit dem Schreiben der Daten begonnen wird. Dies kann zuallererst Zeit verschwenden. Warum nicht anfangen, Teile von Daten zu schreiben, während Sie andere Teile lesen? Vor allem aber kann dieser Ansatz sehr speicherintensiv sein. In einem extremen Szenario, in dem die Eingabedatei größer als der Speicher Ihres Computers ist, funktioniert dieser Ansatz nicht einmal. Die Lösung für dieses Problem besteht darin, nur Iteratoren zu verwenden. Ein Arbeitsbeispiel:Dies liest die Eingabedatei Zeile für Zeile. Sobald eine Zeile gelesen wurde, wird diese Zeile in die Ausgabedatei geschrieben. Schematisch gesehen befindet sich immer nur eine einzige Zeile im Speicher (im Vergleich zum gesamten Dateiinhalt im Speicher, wenn der Readlines / Writelines-Ansatz verwendet wird).
quelle
write()
undwritelines()
sind grundsätzlich gleichwertig und ihre Verwendung ist auch eine Frage des persönlichen Geschmacks. Es ist jedoch wichtig zu beachten, dass für eine extrem lange Liste von Zeichenfolgen (aufgerufenlines
) das Schreiben weniger effizient istf.write('\n'.join(lines))
als fürfor l in line: f.write('%s\n' % l)
. Im ersten Fall wird vor dem Schreiben eine völlig neue und sehr lange Zeichenfolge im Speicher erstellt. Im zweiten Fall werden die Daten stückweise geschrieben.outf.writelines(inf.readlines())
sondern lieberoutf.writelines(inf)
. Die Funktion, die wir nicht mehr verwenden möchten, istreadlines()
nichtwritelines()
.writelines()
, ist seine Semantik, wie erklärt, weniger als ideal. Deshalb habe ich es nie benutzt. Und ich habe es nie verpasst.Wenn Sie nur eine Liste speichern und laden möchten, versuchen Sie es mit Pickle
Essiggurken sparen:
und Laden:
quelle
Eigentlich denke ich, dass das Problem ist, dass Ihre Variablen "Zeilen" schlecht sind. Sie haben Zeilen als Tupel definiert, aber ich glaube, dass write () eine Zeichenfolge erfordert. Sie müssen lediglich Ihre Kommas in Pluszeichen (+) ändern.
sollte arbeiten.
quelle
Übung 16 aus Zed Shaws Buch? Sie können Escape-Zeichen wie folgt verwenden:
quelle
" \n ".join((line1, line2, line3))
.