Eu tenho uma literal de seqüência de caracteres de várias linhas que eu quero fazer uma operação em cada linha, assim:
inputString = """Line 1
Line 2
Line 3"""
Eu quero fazer algo como o seguinte:
for line in inputString:
doStuff()
Eu tenho uma literal de seqüência de caracteres de várias linhas que eu quero fazer uma operação em cada linha, assim:
inputString = """Line 1
Line 2
Line 3"""
Eu quero fazer algo como o seguinte:
for line in inputString:
doStuff()
Respostas:
inputString.splitlines()
Fornecerá uma lista com cada item; o splitlines()
método foi projetado para dividir cada linha em um elemento da lista.
''.splitlines() == []
, não ['']
como com ''.split('\n')
.
Como os outros disseram:
inputString.split('\n') # --> ['Line 1', 'Line 2', 'Line 3']
Isso é idêntico ao acima, mas as funções do módulo de string estão obsoletas e devem ser evitadas:
import string
string.split(inputString, '\n') # --> ['Line 1', 'Line 2', 'Line 3']
Como alternativa, se você deseja que cada linha inclua a sequência de interrupção (CR, LF, CRLF), use o splitlines
método com um True
argumento:
inputString.splitlines(True) # --> ['Line 1\n', 'Line 2\n', 'Line 3']
inputString.split(os.linesep)
usará o terminador de linha específico da plataforma.
Usestr.splitlines()
.
splitlines()
lida com as novas linhas corretamente, diferentemente split("\n")
.
Ele também tem a vantagem mencionada por @efotinis de incluir opcionalmente o caractere de nova linha no resultado da divisão quando chamado com um True
argumento.
Explicação detalhada sobre por que você não deve usar split("\n")
:
\n
, em Python, representa uma quebra de linha do Unix (código decimal ASCII 10), independentemente da plataforma em que você a executa. No entanto, a representação de quebra de linha depende da plataforma . No Windows, \n
há dois caracteres CR
e LF
(códigos decimais ASCII 13 e 10, AKA \r
e \n
), enquanto em qualquer Unix moderno (incluindo OS X), é o caractere único LF
.
print
, por exemplo, funciona corretamente, mesmo que você tenha uma string com terminações de linha que não correspondem à sua plataforma:
>>> print " a \n b \r\n c "
a
b
c
No entanto, a divisão explícita em "\ n" produzirá um comportamento dependente da plataforma:
>>> " a \n b \r\n c ".split("\n")
[' a ', ' b \r', ' c ']
Mesmo se você usar os.linesep
, ele só será dividido de acordo com o separador de nova linha na sua plataforma e falhará se você estiver processando o texto criado em outras plataformas ou com apenas um \n
:
>>> " a \n b \r\n c ".split(os.linesep)
[' a \n b ', ' c ']
splitlines
resolve todos estes problemas:
>>> " a \n b \r\n c ".splitlines()
[' a ', ' b ', ' c ']
A leitura de arquivos no modo de texto atenua parcialmente o problema de representação de nova linha, pois converte o Python \n
na representação de nova linha da plataforma. No entanto, o modo de texto existe apenas no Windows. Nos sistemas Unix, todos os arquivos são abertos no modo binário; portanto, o uso split('\n')
em um sistema UNIX com um arquivo do Windows levará a um comportamento indesejado. Além disso, não é incomum processar seqüências de caracteres com novas linhas potencialmente diferentes de outras fontes, como de um soquete.
splitlines
será dividido em qualquer final de linha. split(os.linesep)
irá falhar ao ler um arquivo do Windows no UNIX, por exemplo
Pode ser um exagero nesse caso específico, mas outra opção envolve o uso StringIO
para criar um objeto parecido com um arquivo
for line in StringIO.StringIO(inputString):
doStuff()
str.split
, não é a necessidade de alocar memória (ele lê a string no local). Uma desvantagem é que é muito mais lento se você usarStringIO
(cerca de 50x). Se você usar cStringIO
, no entanto, é cerca de 2x mais rápido
A postagem original solicitada pelo código que imprime algumas linhas (se forem verdadeiras para alguma condição) mais a seguinte linha. Minha implementação seria esta:
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])
Gostaria que os comentários tivessem uma formatação de texto de código adequada, porque acho que a resposta do @ 1_CR precisa de mais solavancos e gostaria de aumentar sua resposta. Enfim, ele me levou à seguinte técnica; ele usará o cStringIO, se disponível (MAS OBSERVAÇÃO: cStringIO e StringIO não são os mesmos , porque você não pode subclassificar o cStringIO ... é um built-in ... mas, para operações básicas, a sintaxe será idêntica, para que você possa fazer isso ):
try:
import cStringIO
StringIO = cStringIO
except ImportError:
import StringIO
for line in StringIO.StringIO(variable_with_multiline_string):
pass
print line.strip()