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()
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()
Odpowiedzi:
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:
inputString.split('\n') # --> ['Line 1', 'Line 2', 'Line 3']
Jest to identyczne z powyższym, ale funkcje modułu łańcuchowego są przestarzałe i należy ich unikać:
import string
string.split(inputString, '\n') # --> ['Line 1', 'Line 2', 'Line 3']
Alternatywnie, jeśli chcesz, aby każda linia zawierała sekwencję przerwania (CR, LF, CRLF), użyj splitlinesmetody z Trueargumentem:
inputString.splitlines(True) # --> ['Line 1\n', 'Line 2\n', 'Line 3']
inputString.split(os.linesep)użyje terminatora linii specyficznego dla platformy.
Zastosowaniestr.splitlines() .
splitlines()poprawnie obsługuje nowe wiersze, w przeciwieństwie do split("\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 Trueargumentem.
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 \nma dwa znaki CRi LF(kody dziesiętne ASCII 13 i 10, AKA \ri \n), natomiast w każdym nowoczesnym systemie Unix (w tym OS X) jest to pojedynczy znak LF.
print, na przykład działa poprawnie, nawet jeśli masz ciąg z zakończeniami linii, które nie pasują do Twojej platformy:
>>> print " a \n b \r\n c "
a
b
c
Jednak wyraźne podzielenie na „\ n” spowoduje zachowanie zależne od platformy:
>>> " a \n b \r\n c ".split("\n")
[' a ', ' b \r', ' c ']
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:
>>> " a \n b \r\n c ".split(os.linesep)
[' a \n b ', ' c ']
splitlines rozwiązuje wszystkie te problemy:
>>> " a \n b \r\n c ".splitlines()
[' a ', ' b ', ' c ']
Odczytywanie plików w trybie tekstowym częściowo łagodzi problem z reprezentacją nowej linii, ponieważ konwertuje Pythona w nową \nlinię platformy. Jednak tryb tekstowy istnieje tylko w systemie Windows. W systemach Unix wszystkie pliki są otwierane w trybie binarnym, więc użycie split('\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.
splitlineszostanie podzielona na dowolnym zakończeniu linii. split(os.linesep)zawiedzie podczas odczytu pliku systemu Windows w systemie Unix, na przykład
W tym konkretnym przypadku może to być przesada, ale inna opcja wymaga użycia StringIOdo utworzenia obiektu podobnego do pliku
for line in StringIO.StringIO(inputString):
doStuff()
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żyjesz cStringIO, jest około dwa razy szybszy
Pierwotny 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:
text = """1 sfasdf
asdfasdf
2 sfasdf
asdfgadfg
1 asfasdf
sdfasdgf
"""
text = text.splitlines()
rows_to_print = {}
for line in range(len(text)):
if text[line][0] == '1':
rows_to_print = rows_to_print | {line, line + 1}
rows_to_print = sorted(list(rows_to_print))
for i in rows_to_print:
print(text[i])
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ć ):
try:
import cStringIO
StringIO = cStringIO
except ImportError:
import StringIO
for line in StringIO.StringIO(variable_with_multiline_string):
pass
print line.strip()