2012-05-04 14 views
8

No puedo entender por qué el código # 1 devuelve una línea vacía adicional mientras que el código # 2 no lo hace. ¿Alguien podría explicar esto? La diferencia es una coma adicional al final del código # 2.Línea extra en salida al imprimir dentro de un bucle

# Code #1 
file = open('tasks.txt') 

for i, text in enumerate(filer, start=1): 
    if i >= 2 and i <= 4: 
     print "(%d) %s" % (i, text) 

# Code #2 
file = open('tasks.txt') 

for i, text in enumerate(filer, start=1): 
    if i >= 2 and i <= 4: 
     print "(%d) %s" % (i, text), 

Aquí es el contenido de mi archivo tasks.txt:

line 1 
line 2 
line 3 
line 4 
line 5 

resultado de código # 1:

(2) line 2 

(3) line 3 

(4) line 4 

resultado de código # 2 (resultado deseado):

(2) line 2 
(3) line 3 
(4) line 4 

Respuesta

13

El , final en la instrucción de impresión suprimirá un avance de línea. Su primera declaración impresa no tiene una, la segunda sí.

La entrada que lee todavía contiene el \n que causa el avance de línea adicional. Una forma de compensarlo es evitar que la impresión emita un avance de línea utilizando la coma final. Alternativamente, y podría decirse que es un mejor enfoque, puede pelar la nueva línea en la entrada cuando la lea (por ejemplo, usando rstrip())

+0

Gracias, no estaba al tanto de eso. Lo busqué. Parece que Python 3.0 contiene algunas características adicionales de lo que viene a imprimir. Si lo entiendo bien, puedes definir cómo terminar tu línea en Python 3.0+ [lo encontré aquí] (http://docs.python.org/release/3.1.5/whatsnew/3.0.html#print-is-a -función). Y gracias por señalar el error, sí, quise decir el código # 2. Fijo. – finspin

+0

@Jaro Tiene razón, la sección en los documentos señala la diferencia relevante para imprimir entre Python 2.xy 3.x. – Levon

1

Iterar archivos mantiene las líneas nuevas del archivo. Así que hay una nueva línea de su impresión, y una de la cadena.

Una buena forma de probar la semántica de archivos es con StringIO. Echar un vistazo:

>>> from StringIO import StringIO 
>>> x = StringIO("abc\ncde\n") 
>>> for line in x: print repr(line) 
... 
'abc\n' 
'cde\n' 

La coma suprime la nueva línea de la impresión, como dice Levon, de modo que sólo hay la nueva línea de la cadena.

Saco nuevas líneas de cadenas usando s.rstrip('\n'). Elimina cualquier nueva línea final en cualquier formato moderno (Unix, Windows o viejo Mac OS). Entonces puede hacer print "(%d) %s" % (i, text.rstrip('\n')) en su lugar.

+0

¡Gracias por el consejo! – finspin

+0

-1 Si (como deberías) estás abriendo el archivo en modo texto, el separador de línea cambiará a ''\ n'', por lo que todo lo que necesitas es' .rstrip (' \ n ') '. Si eso deja un ''\ r'' al final de su línea, entonces ese'' \ r'' es parte de su ** DATA **, presumiblemente como resultado de que el productor del archivo esté algo confundido. –

+1

@John Estás equivocado. El separador de línea cambia de '\ r \ n' a '\ n' en Windows, pero no en Unix. Es decir: los mismos archivos se comportarán de manera diferente en diferentes sistemas operativos si hacemos lo que sugiere. Tal vez esto es lo que queremos, pero no es lo que dijiste. Si leemos con 'rU', sin embargo, ellos leen lo mismo, y luego no es necesario eliminar '\ r'. –

2

Con el fin de no tener una línea en blanco, es necesario , al final de la instrucción de impresión

Ejemplo:

for i in range(10): 
    print i, 

>>>0 1 2 3 4 5 6 7 8 9 

for i in range(10): 
    print i 

>>> 
0 
1 
2 
3 
4 
5 
6 
7 
8 
9 
+1

En ** python3 ** sería 'para i en rango (10): print (i, end =" ")' – erik

3

La mejor general de respuesta a este problema es despojar al arrastre nueva línea (¡si alguna!) tan pronto como la lea:

f = open('tasks.txt') 
for i, text in enumerate(f, start=1): 
    text = text.rstrip('\n') 
    if i >= 2 and i <= 4: 
     print "(%d) %s" % (i, text) 

De esta forma puede desacoplar su salida de su entrada. . su código de salida puede estar a 20 líneas de distancia o en una función/método diferente o incluso en un módulo diferente. La compensación de una nueva línea en la entrada mediante el uso de una coma al final de la declaración de impresión no es una solución sólida.

1

Hay una solución muy simple para esto.

Digamos que tengo, por los argumentos, un archivo .txt (llamado números.txt), que estoy leyendo a partir de los valores:

234234 
777776 
768768 

Luego, usando el siguiente código:

filename = numbers.txt 

with open(filename) as file_object: 
    for line in file_object: 
     print(line) 

le daría la línea en blanco que usted está teniendo problemas con. Pero con un pequeño cambio, puede deshacerse de las líneas en blanco adicionales utilizando el método rstrip(). Por lo que el código se convierte en:

filename = numbers.txt 

with open(filename) as file_object: 
    for line in file_object: 
     print(line.rstrip()) 

Ahora obtendrá los resultados sin esas molestas líneas en blanco entre ellos!

Cuestiones relacionadas