Więc uczę się Pythona. Przechodzę przez lekcje i natknąłem się na problem, w którym musiałem skondensować bardzo wiele target.write()
w jedną write()
, mając "\n"
pomiędzy każdą zmienną wejściową użytkownika (obiekt write()
).
Wymyśliłem:
nl = "\n"
lines = line1, nl, line2, nl, line3, nl
textdoc.writelines(lines)
Jeśli spróbuję:
textdoc.write(lines)
Otrzymuję błąd. Ale jeśli napiszę:
textdoc.write(line1 + "\n" + line2 + ....)
Wtedy działa dobrze. Dlaczego nie mogę użyć ciągu dla nowej linii w, write()
ale mogę go użyć w writelines()
?
Python 2.7 Kiedy przeszukiwałem google większość znalezionych zasobów było ponad moją głową, nadal jestem laikiem.
python
string
file-io
python-2.x
AbeLinkon
źródło
źródło
lines
w twoim przykładzie nie jest ciągiem. Jest to krotka składająca się z sześciu strun.Odpowiedzi:
writelines
oczekuje iterowalnych łańcuchówwrite
oczekuje pojedynczego ciągu.line1 + "\n" + line2
łączy te ciągi w jeden ciąg przed przekazaniem go dowrite
.Pamiętaj, że jeśli masz wiele linii, możesz użyć
"\n".join(list_of_lines)
.źródło
writelines
oczekuje iterowalnego pliku. Możesz użyć listy, krotki lub generatora.write
zamiast,writelines
jeśli masz wiele linii? Writelines może działać lepiej, ponieważ nie musi tworzyć tymczasowego połączonego ciągu, po prostu iterując po liniach.Dlaczego nie mogę użyć ciągu znaków dla nowej linii w funkcji write (), ale mogę go użyć w writelines ()?
Pomysł jest następujący: jeśli chcesz napisać pojedynczy ciąg, możesz to zrobić za pomocą
write()
. Jeśli masz sekwencję ciągów, możesz je wszystkie zapisać za pomocąwritelines()
.write(arg)
oczekuje łańcucha jako argumentu i zapisuje go do pliku. Jeśli podasz listę ciągów, zgłosi to wyjątek (przy okazji pokaż nam błędy!).writelines(arg)
oczekuje iterowalnego argumentu (obiekt iterowalny może być krotką, listą, łańcuchem lub iteratorem w najbardziej ogólnym sensie). Każdy element zawarty w iteratorze powinien być ciągiem. Podałeś krotkę ciągów, więc wszystko zadziałało.Natura ciągu (ów) nie ma znaczenia dla obu funkcji, tzn. Po prostu zapisują do pliku wszystko, co im podasz. Ciekawe jest to, że
writelines()
nie dodaje samodzielnie znaków nowej linii, więc nazwa metody może być dość myląca. W rzeczywistości zachowuje się jak wyimaginowana metoda o nazwiewrite_all_of_these_strings(sequence)
.Poniżej przedstawiono idiomatyczny sposób w Pythonie, aby zapisać listę ciągów do pliku, zachowując każdy ciąg w osobnym wierszu:
To zajmie się zamknięciem pliku za Ciebie. Konstrukcja
'\n'.join(lines)
konkatenuje (łączy) ciągi znaków z listylines
i używa znaku „\ n” jako kleju. Jest to bardziej wydajne niż korzystanie z+
operatora.Zaczynając od tej samej
lines
sekwencji, kończąc na tym samym wyjściu, ale używającwritelines()
:Wykorzystuje to wyrażenie generatora i dynamicznie tworzy ciągi zakończone znakiem nowej linii.
writelines()
iteruje po tej sekwencji ciągów i zapisuje każdy element.Edycja: Kolejna kwestia, o której powinieneś wiedzieć:
write()
ireadlines()
istniał przedwritelines()
wprowadzeniem.writelines()
został wprowadzony później jako odpowiednikreadlines()
, dzięki czemu można było łatwo napisać treść pliku, który został właśnie odczytany przezreadlines()
:Naprawdę, to jest główny powód, dla którego
writelines
ma tak mylącą nazwę. Dzisiaj nie chcemy już używać tej metody.readlines()
czyta cały plik do pamięci twojego komputera przedwritelines()
rozpoczęciem zapisywania danych. Przede wszystkim może to tracić czas. Dlaczego nie zacząć zapisywać części danych podczas czytania innych części? Ale co najważniejsze, takie podejście może pochłaniać dużo pamięci. W skrajnym scenariuszu, w którym plik wejściowy jest większy niż pamięć komputera, takie podejście nawet nie zadziała. Rozwiązaniem tego problemu jest użycie tylko iteratorów. Działający przykład:To czyta plik wejściowy wiersz po wierszu. Gdy tylko zostanie odczytana jedna linia, ta linia jest zapisywana do pliku wyjściowego. Mówiąc schematycznie, zawsze jest tylko jedna linia w pamięci (w porównaniu do całej zawartości pliku znajdującej się w pamięci w przypadku podejścia readlines / writelines).
źródło
write()
iwritelines()
są w zasadzie równoważne, a ich użycie jest również kwestią osobistego gustu. Należy jednak zauważyć, że w przypadku bardzo długiej listy ciągów (nazywanychlines
) pisanie jest mniej wydajnef.write('\n'.join(lines))
niżfor l in line: f.write('%s\n' % l)
. W pierwszym przypadku przed zapisaniem w pamięci tworzony jest zupełnie nowy i bardzo długi ciąg. W drugim przypadku dane są zapisywane fragmentarycznie.outf.writelines(inf.readlines())
ale raczejoutf.writelines(inf)
. Funkcja nie chcemy używać już toreadlines()
niewritelines()
.writelines()
, jego semantyka jest, jak wyjaśniono, mniej niż idealna. Dlatego nigdy go nie używałem. I nigdy tego nie przegapiłem.jeśli chcesz tylko zapisać i załadować listę, wypróbuj Pickle
Oszczędność marynaty:
i ładowanie:
źródło
Właściwie myślę, że problem polega na tym, że zmienne „linie” są złe. Zdefiniowałeś wiersze jako krotkę, ale uważam, że write () wymaga ciągu. Wszystko, co musisz zmienić, to przecinki na plusy (+).
powinno działać.
źródło
Ćwiczenie 16 z książki Zeda Shawa? Możesz użyć znaków ucieczki w następujący sposób:
źródło
" \n ".join((line1, line2, line3))
.