Mam wieloliniowy literał łańcuchowy, który chcę wykonać operację na każdej linii, na przykład:
inputString = """Line 1
Line 2
Line 3"""
Chcę zrobić coś takiego:
for line in inputString:
doStuff()
inputString.splitlines()
Daje ci listę z każdym elementem, splitlines()
metoda ma na celu podzielenie każdej linii na element listy.
''.splitlines() == []
, że nie['']
tak jak w przypadku''.split('\n')
.Tak jak inni powiedzieli:
Jest to identyczne z powyższym, ale funkcje modułu łańcuchowego są przestarzałe i należy ich unikać:
Alternatywnie, jeśli chcesz, aby każda linia zawierała sekwencję przerwania (CR, LF, CRLF), użyj
splitlines
metody zTrue
argumentem:źródło
inputString.split(os.linesep)
użyje terminatora linii specyficznego dla platformy.Zastosowanie
str.splitlines()
.splitlines()
poprawnie obsługuje nowe wiersze, w przeciwieństwie dosplit("\n")
.Ma również tę zaletę, o której wspomina @efotinis, polegającą na opcjonalnym włączeniu znaku nowej linii w wyniku podziału, gdy zostanie wywołany z
True
argumentem.Szczegółowe wyjaśnienie, dlaczego nie należy używać
split("\n")
:\n
, w Pythonie reprezentuje uniksowy podział linii (kod dziesiętny ASCII 10), niezależnie od platformy, na której jest uruchamiany. Jednak reprezentacja podziału linii zależy od platformy . W systemie Windows\n
ma dwa znakiCR
iLF
(kody dziesiętne ASCII 13 i 10, AKA\r
i\n
), natomiast w każdym nowoczesnym systemie Unix (w tym OS X) jest to pojedynczy znakLF
.print
, na przykład działa poprawnie, nawet jeśli masz ciąg z zakończeniami linii, które nie pasują do Twojej platformy:Jednak wyraźne podzielenie na „\ n” spowoduje zachowanie zależne od platformy:
Nawet jeśli go użyjesz
os.linesep
, zostanie on podzielony tylko zgodnie z separatorem nowej linii na Twojej platformie i zakończy się niepowodzeniem, jeśli przetwarzasz tekst utworzony na innych platformach lub z czystym\n
:splitlines
rozwiązuje wszystkie te problemy:Odczytywanie plików w trybie tekstowym częściowo łagodzi problem z reprezentacją nowej linii, ponieważ konwertuje Pythona w nową
\n
linię platformy. Jednak tryb tekstowy istnieje tylko w systemie Windows. W systemach Unix wszystkie pliki są otwierane w trybie binarnym, więc użyciesplit('\n')
w systemie UNIX z plikiem Windows spowoduje niepożądane zachowanie. Ponadto nie jest niczym niezwykłym przetwarzanie ciągów znaków z potencjalnie różnymi znakami nowej linii z innych źródeł, takich jak gniazdo.źródło
splitlines
zostanie podzielona na dowolnym zakończeniu linii.split(os.linesep)
zawiedzie podczas odczytu pliku systemu Windows w systemie Unix, na przykładW tym konkretnym przypadku może to być przesada, ale inna opcja wymaga użycia
StringIO
do utworzenia obiektu podobnego do plikuźródło
str.split
, że nie wymaga alokacji pamięci (odczytuje ciąg w miejscu). Wadą jest to, że jest znacznie wolniejszy, jeśli używaszStringIO
(około 50x). Jeśli jednak użyjeszcStringIO
, jest około dwa razy szybszyPierwotny post zażądał kodu, który drukuje niektóre wiersze (jeśli są prawdziwe dla niektórych warunków) plus następny wiersz. Moja implementacja będzie następująca:
źródło
Chciałbym, aby komentarze miały odpowiednie formatowanie tekstu, ponieważ uważam, że odpowiedź @ 1_CR wymaga więcej nierówności i chciałbym rozszerzyć jego odpowiedź. W każdym razie poprowadził mnie do następującej techniki; użyje cStringIO, jeśli jest dostępny (ALE UWAGA: cStringIO i StringIO nie są takie same , ponieważ nie można podklasować cStringIO ... to jest wbudowany ... ale dla podstawowych operacji składnia będzie identyczna, więc możesz to zrobić ):
źródło