Tengo un literal de cadena de varias líneas que quiero hacer una operación en cada línea, así:
inputString = """Line 1
Line 2
Line 3"""
Quiero hacer algo como lo siguiente:
for line in inputString:
doStuff()
Tengo un literal de cadena de varias líneas que quiero hacer una operación en cada línea, así:
inputString = """Line 1
Line 2
Line 3"""
Quiero hacer algo como lo siguiente:
for line in inputString:
doStuff()
Respuestas:
inputString.splitlines()
Le dará una lista con cada elemento, el splitlines()
método está diseñado para dividir cada línea en un elemento de la lista.
''.splitlines() == []
, no ['']
como con ''.split('\n')
.
Como los otros dijeron:
inputString.split('\n') # --> ['Line 1', 'Line 2', 'Line 3']
Esto es idéntico a lo anterior, pero las funciones del módulo de cadena están en desuso y deben evitarse:
import string
string.split(inputString, '\n') # --> ['Line 1', 'Line 2', 'Line 3']
Alternativamente, si desea que cada línea incluya la secuencia de corte (CR, LF, CRLF), use el splitlines
método con un True
argumento:
inputString.splitlines(True) # --> ['Line 1\n', 'Line 2\n', 'Line 3']
inputString.split(os.linesep)
utilizará el terminador de línea específico de la plataforma.
Usostr.splitlines()
.
splitlines()
maneja las nuevas líneas correctamente, a diferencia split("\n")
.
También tiene la ventaja mencionada por @efotinis de incluir opcionalmente el carácter de nueva línea en el resultado dividido cuando se llama con un True
argumento.
Explicación detallada sobre por qué no debe usar split("\n")
:
\n
, en Python, representa un salto de línea Unix (código decimal ASCII 10), independientemente de la plataforma donde lo ejecute. Sin embargo, la representación de salto de línea depende de la plataforma . En Windows, \n
tiene dos caracteres, CR
y LF
(códigos decimales ASCII 13 y 10, AKA \r
y \n
), mientras que en cualquier Unix moderno (incluido OS X), es el carácter único LF
.
print
, por ejemplo, funciona correctamente incluso si tiene una cadena con terminaciones de línea que no coinciden con su plataforma:
>>> print " a \n b \r\n c "
a
b
c
Sin embargo, dividirse explícitamente en "\ n", generará un comportamiento dependiente de la plataforma:
>>> " a \n b \r\n c ".split("\n")
[' a ', ' b \r', ' c ']
Incluso si lo usa os.linesep
, solo se dividirá de acuerdo con el separador de nueva línea en su plataforma, y fallará si está procesando texto creado en otras plataformas, o simplemente \n
:
>>> " a \n b \r\n c ".split(os.linesep)
[' a \n b ', ' c ']
splitlines
resuelve todos estos problemas:
>>> " a \n b \r\n c ".splitlines()
[' a ', ' b ', ' c ']
La lectura de archivos en modo de texto mitiga parcialmente el problema de la representación de nueva línea, ya que convierte Python \n
en la representación de nueva línea de la plataforma. Sin embargo, el modo de texto solo existe en Windows. En los sistemas Unix, todos los archivos se abren en modo binario, por lo que su uso split('\n')
en un sistema UNIX con un archivo de Windows provocará un comportamiento no deseado. Además, no es inusual procesar cadenas con líneas nuevas potencialmente diferentes de otras fuentes, como desde un socket.
splitlines
se dividirá en cualquier final de línea. split(os.linesep)
fallará al leer un archivo de Windows en Unix, por ejemplo
Podría ser excesivo en este caso particular, pero otra opción implica usar StringIO
para crear un objeto similar a un archivo
for line in StringIO.StringIO(inputString):
doStuff()
str.split
, es que no necesita asignar memoria (lee la cadena en el lugar). Una desventaja es que es mucho más lento si lo usaStringIO
(aproximadamente 50x). cStringIO
Sin embargo,
La publicación original solicitó el código que imprime algunas filas (si son ciertas para alguna condición) más la siguiente fila. Mi implementación sería 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])
Deseo que los comentarios tengan el formato de texto de código adecuado, porque creo que la respuesta de @ 1_CR necesita más protuberancias, y me gustaría aumentar su respuesta. De todos modos, me llevó a la siguiente técnica; usará cStringIO si está disponible (PERO NOTA: cStringIO y StringIO no son lo mismo , porque no se puede subclasificar cStringIO ... es una función incorporada ... pero para las operaciones básicas la sintaxis será idéntica, por lo que puede hacer esto ):
try:
import cStringIO
StringIO = cStringIO
except ImportError:
import StringIO
for line in StringIO.StringIO(variable_with_multiline_string):
pass
print line.strip()