Ich habe ein mehrzeiliges Zeichenfolgenliteral, mit dem ich in jeder Zeile eine Operation ausführen möchte, wie folgt:
inputString = """Line 1
Line 2
Line 3"""
Ich möchte so etwas wie das Folgende tun:
for line in inputString:
doStuff()
Ich habe ein mehrzeiliges Zeichenfolgenliteral, mit dem ich in jeder Zeile eine Operation ausführen möchte, wie folgt:
inputString = """Line 1
Line 2
Line 3"""
Ich möchte so etwas wie das Folgende tun:
for line in inputString:
doStuff()
Antworten:
inputString.splitlines()
Wenn Sie eine Liste mit jedem Element erhalten, ist die splitlines()
Methode so konzipiert, dass jede Zeile in ein Listenelement aufgeteilt wird.
''.splitlines() == []
auch nicht ['']
wie bei ''.split('\n')
.
Wie die anderen sagten:
inputString.split('\n') # --> ['Line 1', 'Line 2', 'Line 3']
Dies ist identisch mit dem oben genannten, aber die Funktionen des String-Moduls sind veraltet und sollten vermieden werden:
import string
string.split(inputString, '\n') # --> ['Line 1', 'Line 2', 'Line 3']
Wenn Sie alternativ möchten, dass jede Zeile die Unterbrechungssequenz (CR, LF, CRLF) enthält, verwenden Sie alternativ die splitlines
Methode mit einem True
Argument:
inputString.splitlines(True) # --> ['Line 1\n', 'Line 2\n', 'Line 3']
inputString.split(os.linesep)
verwendet den plattformspezifischen Leitungsabschluss.
Verwenden Siestr.splitlines()
.
splitlines()
behandelt Zeilenumbrüche im Gegensatz zu split("\n")
.
Es hat auch den von @efotinis erwähnten Vorteil, dass das Zeilenumbruchzeichen optional in das Teilungsergebnis aufgenommen wird, wenn es mit einem True
Argument aufgerufen wird .
Detaillierte Erklärung, warum Sie nicht verwenden sollten split("\n")
:
\n
stellt in Python einen Unix-Zeilenumbruch (ASCII-Dezimalcode 10) dar, unabhängig von der Plattform, auf der Sie ihn ausführen. Die Darstellung des Zeilenumbruchs ist jedoch plattformabhängig . Unter Windows sind \n
es zwei Zeichen CR
und LF
(ASCII-Dezimalcodes 13 und 10, AKA \r
und \n
), während es unter jedem modernen Unix (einschließlich OS X) das einzelne Zeichen ist LF
.
print
Funktioniert beispielsweise auch dann ordnungsgemäß, wenn Sie eine Zeichenfolge mit Zeilenenden haben, die nicht zu Ihrer Plattform passen:
>>> print " a \n b \r\n c "
a
b
c
Eine explizite Aufteilung auf "\ n" führt jedoch zu einem plattformabhängigen Verhalten:
>>> " a \n b \r\n c ".split("\n")
[' a ', ' b \r', ' c ']
Selbst wenn Sie verwenden os.linesep
, wird es nur gemäß dem Zeilenumbruchtrennzeichen auf Ihrer Plattform aufgeteilt und schlägt fehl, wenn Sie Text verarbeiten, der auf anderen Plattformen erstellt wurde, oder mit einem bloßen \n
:
>>> " a \n b \r\n c ".split(os.linesep)
[' a \n b ', ' c ']
splitlines
löst all diese Probleme:
>>> " a \n b \r\n c ".splitlines()
[' a ', ' b ', ' c ']
Durch das Lesen von Dateien im Textmodus wird das Problem der Zeilenumbruchdarstellung teilweise verringert, da Pythons \n
in die Zeilenumbruchdarstellung der Plattform konvertiert werden. Der Textmodus ist jedoch nur unter Windows verfügbar. Auf Unix-Systemen werden alle Dateien im Binärmodus geöffnet. Die Verwendung split('\n')
in einem UNIX-System mit einer Windows-Datei führt daher zu unerwünschtem Verhalten. Es ist auch nicht ungewöhnlich, Zeichenfolgen mit möglicherweise unterschiedlichen Zeilenumbrüchen aus anderen Quellen zu verarbeiten, z. B. aus einem Socket.
splitlines
der an jedem Zeilenende geteilt wird. split(os.linesep)
wird zum Beispiel beim Lesen einer Windows-Datei unter Unix
Könnte in diesem speziellen Fall übertrieben sein, aber eine andere Option besteht StringIO
darin, ein dateiähnliches Objekt zu erstellen
for line in StringIO.StringIO(inputString):
doStuff()
str.split
ist , dass kein Speicher zugewiesen werden muss (sie liest die Zeichenfolge an Ort und Stelle). Ein Nachteil ist, dass es viel langsamer ist, wenn Sie verwendenStringIO
(ca. 50x). Wenn Sie cStringIO
jedoch verwenden, ist es etwa 2x schneller
Der ursprüngliche Beitrag forderte Code an, der einige Zeilen druckt (sofern sie für eine bestimmte Bedingung zutreffen), sowie die folgende Zeile. Meine Implementierung wäre folgende:
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])
Ich wünschte, Kommentare hätten die richtige Code-Text-Formatierung, da ich denke, dass die Antwort von @ 1_CR mehr Unebenheiten erfordert, und ich möchte seine Antwort ergänzen. Wie auch immer, er führte mich zu der folgenden Technik; Wenn verfügbar, wird cStringIO verwendet (ABER HINWEIS: cStringIO und StringIO sind nicht identisch , da Sie cStringIO nicht unterordnen können ... es ist integriert ... aber für grundlegende Operationen ist die Syntax identisch, sodass Sie dies tun können ):
try:
import cStringIO
StringIO = cStringIO
except ImportError:
import StringIO
for line in StringIO.StringIO(variable_with_multiline_string):
pass
print line.strip()