У мене є багаторядковий рядковий літерал, який я хочу зробити в кожному рядку, наприклад:
inputString = """Line 1
Line 2
Line 3"""
Я хочу зробити щось подібне:
for line in inputString:
doStuff()
У мене є багаторядковий рядковий літерал, який я хочу зробити в кожному рядку, наприклад:
inputString = """Line 1
Line 2
Line 3"""
Я хочу зробити щось подібне:
for line in inputString:
doStuff()
Відповіді:
inputString.splitlines()
Дасть вам список з кожним елементом, splitlines()
метод призначений для розділення кожного рядка на елемент списку.
''.splitlines() == []
, ['']
як не так ''.split('\n')
.
Як казали інші:
inputString.split('\n') # --> ['Line 1', 'Line 2', 'Line 3']
Це ідентично вищесказаному, але функції модульного рядка застаріли і їх слід уникати:
import string
string.split(inputString, '\n') # --> ['Line 1', 'Line 2', 'Line 3']
Крім того, якщо ви хочете, щоб кожен рядок включав послідовність розриву (CR, LF, CRLF), використовуйте splitlines
метод з True
аргументом:
inputString.splitlines(True) # --> ['Line 1\n', 'Line 2\n', 'Line 3']
inputString.split(os.linesep)
буде використовувати конкретний лінійний термінатор для платформи.
Використовуйтеstr.splitlines()
.
splitlines()
обробляє нові лінії правильно, на відміну від split("\n")
.
Він також має перевагу, згадану @efotinis, в тому, що необов'язково включати символ нового рядка в результат розбиття, коли викликається True
аргументом.
Детальне пояснення того, чому не слід використовувати split("\n")
:
\n
, в Python, являє собою розрив рядків Unix (десятковий код ASCII 10), незалежно від платформи, де ви його запускаєте. Однак представлення рядкової лінії залежить від платформи . У Windows \n
є два символи ( CR
та LF
десяткових кодів ASCII 13 і 10, AKA \r
і \n
), тоді як на будь-якому сучасному Unix (включаючи OS X) це єдиний символ LF
.
print
, наприклад, працює правильно, навіть якщо у вас є рядок із закінченнями рядків, які не відповідають вашій платформі:
>>> print " a \n b \r\n c "
a
b
c
Однак явне розділення на "\ n" призведе до поведінки, залежно від платформи:
>>> " a \n b \r\n c ".split("\n")
[' a ', ' b \r', ' c ']
Навіть якщо ви використовуєте os.linesep
, він розділиться лише відповідно до роздільника нового рядка на вашій платформі, і вийде з ладу, якщо ви обробляєте текст, створений на інших платформах, або з голою \n
:
>>> " a \n b \r\n c ".split(os.linesep)
[' a \n b ', ' c ']
splitlines
вирішує всі ці проблеми:
>>> " a \n b \r\n c ".splitlines()
[' a ', ' b ', ' c ']
Читання файлів у текстовому режимі частково пом’якшує проблему представлення нового рядка, оскільки вона перетворює Python \n
в представлення нового рядка платформи. Однак текстовий режим існує лише в Windows. У системах Unix всі файли відкриваються у двійковому режимі, тому використання split('\n')
в системі UNIX з файлом Windows призведе до небажаної поведінки. Крім того, незвично обробляти рядки з потенційно різними новими рядками з інших джерел, наприклад, з сокета.
splitlines
буде розділено на будь-який рядок, що закінчується. split(os.linesep)
не вдасться прочитати файл Windows в unix, наприклад
У цьому конкретному випадку може бути зайвим, але інший варіант передбачає використання StringIO
для створення файлоподібного об’єкта
for line in StringIO.StringIO(inputString):
doStuff()
str.split
, що не потрібно виділяти пам'ять (він читає рядок на місці). Недоліком є те, що це набагато повільніше, якщо ви користуєтесьStringIO
(приблизно 50 разів). Якщо ви користуєтеся cStringIO
, однак, це приблизно в 2 рази швидше
Оригінальна публікація запитується для коду, який друкує деякі рядки (якщо вони відповідають дійсності для певної умови) плюс наступний рядок. Моєю реалізацією було б таке:
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])
Я б хотів, щоб коментарі мали правильне форматування тексту коду, тому що я думаю, що відповідь @ 1_CR потребує більше ударів, і я хотів би доповнити його відповідь. У будь-якому випадку, він привів мене до наступної техніки; вона буде використовувати cStringIO, якщо вона доступна (АЛЕ ПРИМІТКА: cStringIO і StringIO не однакові , тому що ви не можете підклас cStringIO ... це вбудований ... але для основних операцій синтаксис буде ідентичним, тому ви можете це зробити ):
try:
import cStringIO
StringIO = cStringIO
except ImportError:
import StringIO
for line in StringIO.StringIO(variable_with_multiline_string):
pass
print line.strip()