Saya memiliki string multi-line literal yang ingin saya lakukan operasi pada setiap baris, seperti:
inputString = """Line 1
Line 2
Line 3"""
Saya ingin melakukan sesuatu seperti berikut:
for line in inputString:
doStuff()
Saya memiliki string multi-line literal yang ingin saya lakukan operasi pada setiap baris, seperti:
inputString = """Line 1
Line 2
Line 3"""
Saya ingin melakukan sesuatu seperti berikut:
for line in inputString:
doStuff()
Jawaban:
inputString.splitlines()
Akan memberi Anda daftar dengan setiap item, splitlines()
metode ini dirancang untuk membagi setiap baris menjadi elemen daftar.
''.splitlines() == []
, bukan ['']
dengan ''.split('\n')
.
Seperti yang dikatakan orang lain:
inputString.split('\n') # --> ['Line 1', 'Line 2', 'Line 3']
Ini identik dengan yang di atas, tetapi fungsi modul string sudah usang dan harus dihindari:
import string
string.split(inputString, '\n') # --> ['Line 1', 'Line 2', 'Line 3']
Atau, jika Anda ingin setiap baris menyertakan urutan istirahat (CR, LF, CRLF), gunakan splitlines
metode ini dengan True
argumen:
inputString.splitlines(True) # --> ['Line 1\n', 'Line 2\n', 'Line 3']
inputString.split(os.linesep)
akan menggunakan terminator jalur khusus platform.
Menggunakan str.splitlines()
.
splitlines()
menangani baris baru dengan benar, tidak seperti split("\n")
.
Ini juga memiliki keunggulan yang disebutkan oleh @efotinis secara opsional termasuk karakter baris baru dalam hasil split ketika dipanggil dengan True
argumen.
Penjelasan terperinci tentang mengapa Anda tidak harus menggunakan split("\n")
:
\n
, dengan Python, merepresentasikan line-break Unix (kode desimal ASCII 10), terlepas dari platform tempat Anda menjalankannya. Namun, representasi linebreak bergantung pada platform . Pada Windows, \n
adalah dua karakter, CR
dan LF
(ASCII kode desimal 13 dan 10, AKA \r
dan \n
), sedangkan pada setiap Unix modern (termasuk OS X), itu adalah karakter tunggal LF
.
print
, misalnya, berfungsi dengan benar bahkan jika Anda memiliki string dengan ujung garis yang tidak cocok dengan platform Anda:
>>> print " a \n b \r\n c "
a
b
c
Namun, pemisahan secara eksplisit pada "\ n", akan menghasilkan perilaku yang bergantung pada platform:
>>> " a \n b \r\n c ".split("\n")
[' a ', ' b \r', ' c ']
Bahkan jika Anda menggunakan os.linesep
, itu hanya akan terpecah sesuai dengan pemisah baris baru pada platform Anda, dan akan gagal jika Anda sedang memproses teks yang dibuat di platform lain, atau dengan telanjang \n
:
>>> " a \n b \r\n c ".split(os.linesep)
[' a \n b ', ' c ']
splitlines
menyelesaikan semua masalah ini:
>>> " a \n b \r\n c ".splitlines()
[' a ', ' b ', ' c ']
Membaca file dalam mode teks sebagian mengurangi masalah representasi baris baru, karena mengubah Python \n
menjadi representasi baris baru platform. Namun, mode teks hanya ada di Windows. Pada sistem Unix, semua file dibuka dalam mode biner, jadi menggunakan split('\n')
sistem UNIX dengan file Windows akan menyebabkan perilaku yang tidak diinginkan. Selain itu, tidak biasa untuk memproses string dengan baris baru yang berpotensi berbeda dari sumber lain, seperti dari soket.
splitlines
akan dipisah pada akhir baris apa pun . split(os.linesep)
akan gagal ketika membaca file windows di unix, misalnya
Mungkin berlebihan dalam kasus khusus ini tetapi opsi lain melibatkan penggunaan StringIO
untuk membuat objek seperti file
for line in StringIO.StringIO(inputString):
doStuff()
str.split
, tidak perlu mengalokasikan memori apa pun (membaca string di tempat). Kerugiannya adalah jauh lebih lambat jika Anda menggunakanStringIO
(sekitar 50x). Namun, jika Anda menggunakannya cStringIO
, ini 2x lebih cepat
Posting asli meminta kode yang mencetak beberapa baris (jika benar untuk beberapa kondisi) ditambah baris berikut. Implementasi saya adalah ini:
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])
Saya berharap komentar memiliki format teks kode yang tepat, karena saya pikir jawaban @ 1_CR perlu lebih banyak gundukan, dan saya ingin menambah jawabannya. Bagaimanapun, Dia membawa saya ke teknik berikut; ia akan menggunakan cStringIO jika tersedia (TETAPI CATATAN: cStringIO dan StringIO tidak sama , karena Anda tidak dapat mensubklasifikasikan cStringIO ... itu adalah built-in ... tetapi untuk operasi dasar sintaksinya akan sama, sehingga Anda dapat melakukan ini ):
try:
import cStringIO
StringIO = cStringIO
except ImportError:
import StringIO
for line in StringIO.StringIO(variable_with_multiline_string):
pass
print line.strip()