Imprimir en una línea dinámicamente

Me gustaría hacer varias declaraciones que den resultados estándar sin ver nuevas líneas entre las declaraciones.

Específicamente, supongamos que tengo:

for item in range(1,100): print item 

El resultado es:

 1 2 3 4 . . . 

Cómo conseguir que esto se vea como:

 1 2 3 4 5 ... 

Aún mejor, ¿es posible imprimir el número único sobre el último número, por lo que solo hay un número en la pantalla a la vez?

Cambiar el print item a:

  • print item, en Python 2.7
  • print(item, end=" ") en Python 3

Si desea imprimir los datos dinámicamente use la siguiente syntax:

  • print(item, sep=' ', end='', flush=True) en Python 3

Por cierto … cómo actualizarlo cada vez para que imprima mi en un lugar, solo cambia el número.

En general, la forma de hacerlo es con los códigos de control de terminal . Este es un caso particularmente simple, para el que solo necesita un carácter especial: U + 000D CARRIAGE RETURN, que está escrito '\r' en Python (y en muchos otros idiomas). Aquí hay un ejemplo completo basado en su código:

 from sys import stdout from time import sleep for i in range(1,20): stdout.write("\r%d" % i) stdout.flush() sleep(1) stdout.write("\n") # move the cursor to the next line 

Algunas cosas sobre esto que pueden ser sorprendentes:

  • El \r va al principio de la cadena de modo que, mientras el progtwig se está ejecutando, el cursor siempre estará después del número. Esto no es solo cosmético: algunos emuladores de terminal se confunden mucho si lo haces al revés.
  • Si no incluye la última línea, entonces, una vez que finalice el progtwig, su shell imprimirá su solicitud encima del número.
  • El stdout.flush es necesario en algunos sistemas, o no obtendrá ningún resultado. Otros sistemas pueden no requerirlo, pero no hace ningún daño.

Si descubre que esto no funciona, lo primero que debe sospechar es que su emulador de terminal tiene errores. El progtwig vttest puede ayudarte a probarlo.

Podría reemplazar stdout.write con una statement de print , pero prefiero no mezclar la print con el uso directo de objetos de archivo.

Utilice el print item, para hacer que la statement de impresión omita la nueva línea.

En Python 3, es print(item, end=" ") .

Si desea que todos los números se muestren en el mismo lugar, use por ejemplo (Python 2.7):

 to = 20 digits = len(str(to - 1)) delete = "\b" * (digits + 1) for i in range(to): print "{0}{1:{2}}".format(delete, i, digits), 

En Python 3, es un poco más complicado; Aquí debe vaciar sys.stdout o no imprimirá nada hasta que finalice el ciclo:

 import sys to = 20 digits = len(str(to - 1)) delete = "\b" * (digits) for i in range(to): print("{0}{1:{2}}".format(delete, i, digits), end="") sys.stdout.flush() 

Como los otros ejemplos,
Utilizo un enfoque similar, pero en lugar de dedicar tiempo a calcular la última longitud de salida, etc.

Simplemente uso el código ANSI para volver al principio de la línea y luego borrar toda la línea antes de imprimir mi salida de estado actual.

 import sys class Printer(): """Print things to stdout on one line dynamically""" def __init__(self,data): sys.stdout.write("\r\x1b[K"+data.__str__()) sys.stdout.flush() 

Para usar en tu bucle de iteración, solo deberías llamar algo como:

 x = 1 for f in fileList: ProcessFile(f) output = "File number %d completed." % x Printer(output) x += 1 

Ver más aquí

Puede agregar una coma al final de su statement de impresión para imprimir un espacio en lugar de una nueva línea en cada iteración:

 print item, 

Alternativamente, si está usando Python 2.6 o posterior, puede usar la nueva función de impresión, que le permitiría especificar que ni siquiera debería aparecer un espacio al final de cada elemento que se está imprimiendo (o permitirle especificar el extremo en el que se encuentra). querer):

 from __future__ import print_function ... print(item, end="") 

Finalmente, puede escribir directamente en la salida estándar importándolo desde el módulo sys, que devuelve un objeto similar a un archivo:

 from sys import stdout ... stdout.write( str(item) ) 

cambio

 print item 

a

 print "\033[K", item, "\r", sys.stdout.flush() 
  • “\ 033 [K” se despeja hasta el final de la línea
  • el \ r, vuelve al principio de la línea
  • La statement de descarga se asegura de que se muestre de inmediato para que obtenga una salida en tiempo real.

Creo que una simple unión debería funcionar:

 nl = [] for x in range(1,10):nl.append(str(x)) print ' '.join(nl) 

Otra respuesta que estoy usando en 2.7 donde solo estoy imprimiendo un “.” cada vez que se ejecuta un bucle (para indicar al usuario que las cosas todavía se están ejecutando) es esto:

 print "\b.", 

Imprime el “.” Caracteres sin espacios entre cada uno. Se ve un poco mejor y funciona bastante bien. El \ b es un carácter de retroceso para aquellos que se preguntan.

“Por cierto … cómo actualizarlo cada vez para que imprima mi en un solo lugar, simplemente cambie el número”.

Es un tema realmente complicado. Lo que sugirió zack (emitir códigos de control de consola) es una forma de lograrlo.

Puede usar (n) curses, pero eso funciona principalmente en * nixes.

En Windows (y aquí va la parte interesante) que rara vez se menciona (no entiendo por qué) puede usar enlaces Python para WinAPI ( http://sourceforge.net/projects/pywin32/ también con ActivePython por defecto) – no es Que duro y funciona bien. Aquí hay un pequeño ejemplo:

 import win32console, time output_handle = win32console.GetStdHandle( win32console.STD_OUTPUT_HANDLE ) info = output_handle.GetConsoleScreenBufferInfo() pos = info["CursorPosition"] for i in "\\|/-\\|/-": output_handle.WriteConsoleOutputCharacter( i, pos ) time.sleep( 1 ) 

O, si desea utilizar print (statement o función, no hay diferencia):

 import win32console, time output_handle = win32console.GetStdHandle( win32console.STD_OUTPUT_HANDLE ) info = output_handle.GetConsoleScreenBufferInfo() pos = info["CursorPosition"] for i in "\\|/-\\|/-": print i output_handle.SetConsoleCursorPosition( pos ) time.sleep( 1 ) 

win32console módulo win32console te permite hacer muchas más cosas interesantes con la consola de Windows … No soy un gran fanático de WinAPI, pero recientemente me di cuenta de que al menos la mitad de mi antipatía hacia ella se debía al escribir el código WinAPI en enlaces C – pythonic Son mucho más fáciles de usar.

Todas las demás respuestas son geniales y de tipo python, por supuesto, pero … ¿Qué pasa si quisiera imprimir en la línea anterior ? ¿O escriba texto de varias líneas, que lo borre y vuelva a escribir las mismas líneas? Mi solución lo hace posible.

Para hacer que los números se sobrescriban entre sí, puedes hacer algo como esto:

 for i in range(1,100): print "\r",i, 

Eso debería funcionar siempre que el número esté impreso en la primera columna.

EDITAR: Aquí hay una versión que funcionará incluso si no está impresa en la primera columna.

 prev_digits = -1 for i in range(0,1000): print("%s%d" % ("\b"*(prev_digits + 1), i)), prev_digits = len(str(i)) 

Debo tener en cuenta que este código se probó y funciona bien en Python 2.5 en Windows, en la consola de Windows. Según algunos otros, es posible que se requiera un lavado de la salida estándar para ver los resultados. YMMV.

 In [9]: print? Type: builtin_function_or_method Base Class:  String Form:  Namespace: Python builtin Docstring: print(value, ..., sep=' ', end='\n', file=sys.stdout) Prints the values to a stream, or to sys.stdout by default. Optional keyword arguments: file: a file-like object (stream); defaults to the current sys.stdout. sep: string inserted between values, default a space. end: string appended after the last value, default a newline. 
 for i in xrange(1,100): print i, 

para Python 2.7

 for x in range(0, 3): print x, 

para Python 3

 for x in range(0, 3): print(x, end=" ") 

Si solo desea imprimir los números, puede evitar el bucle.

 # python 3 import time startnumber = 1 endnumber = 100 # solution A without a for loop start_time = time.clock() m = map(str, range(startnumber, endnumber + 1)) print(' '.join(m)) end_time = time.clock() timetaken = (end_time - start_time) * 1000 print('took {0}ms\n'.format(timetaken)) # solution B: with a for loop start_time = time.clock() for i in range(startnumber, endnumber + 1): print(i, end=' ') end_time = time.clock() timetaken = (end_time - start_time) * 1000 print('\ntook {0}ms\n'.format(timetaken)) 

1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 86 87 88 89 90 91 92 93 95 96 97 98 99 100 tomó 21.1986929975ms

1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 86 87 88 89 90 91 92 93 95 96 97 98 99 100 tomó 491.466823551ms

La mejor manera de lograr esto es usar el caracter

Solo prueba el siguiente código:

 import time for n in range(500): print(n, end='\r') time.sleep(0.01) print() # start new line so most recently printed number stays 

En Python 3 puedes hacerlo de esta manera:

 for item in range(1,10): print(item, end =" ") 

Salidas:

 1 2 3 4 5 6 7 8 9 

Tupla: Puedes hacer lo mismo con una tupla:

 tup = (1,2,3,4,5) for n in tup: print(n, end = " - ") 

Salidas:

 1 - 2 - 3 - 4 - 5 - 

Otro ejemplo:

 list_of_tuples = [(1,2),('A','B'), (3,4), ('Cat', 'Dog')] for item in list_of_tuples: print(item) 

Salidas:

 (1, 2) ('A', 'B') (3, 4) ('Cat', 'Dog') 

Incluso puedes desempacar tu tupla de esta manera:

 list_of_tuples = [(1,2),('A','B'), (3,4), ('Cat', 'Dog')] # Tuple unpacking so that you can deal with elements inside of the tuple individually for (item1, item2) in list_of_tuples: print(item1, item2) 

Salidas:

 1 2 AB 3 4 Cat Dog 

otra variación:

 list_of_tuples = [(1,2),('A','B'), (3,4), ('Cat', 'Dog')] for (item1, item2) in list_of_tuples: print(item1) print(item2) print('\n') 

Salidas:

 1 2 A B 3 4 Cat Dog 

Para Python (2.7)

  l="" #empty string variable for item in range(1,100): item=str(item) #converting each element to string l=l+" "+item #concating each element l.lstrip() # deleting the space that was created initially print l #prining the whole string 

Python 3

  l="" for item in range(1,100): item=str(item) l=l+" "+item l.lstrip() print(l)