Imprimer en une seule ligne de façon dynamique

je voudrais faire plusieurs déclarations qui donnent la sortie standard sans voir de nouvelles lignes entre les déclarations.

en particulier, supposons que j'ai:

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

le résultat est:

1
2
3
4
.
.
.

de la Façon de faire cela au lieu de le regarder comme:

1 2 3 4 5 ...

Encore mieux, est-il possible d'imprimer le numéro unique plus le dernier numéro, si un seul numéro est sur le l'écran à un moment?

238
demandé sur unutbu 2010-07-14 23:03:37

17 réponses

modifier print item en:

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

si vous voulez imprimer les données de façon dynamique utiliser la syntaxe suivante:

  • print(item, sep=' ', end='', flush=True) en Python 3
395
répondu ewall 2016-11-29 07:47:07

soit dit en passant...... Comment le rafraîchir à chaque fois pour qu'il imprime mi dans un endroit juste changer le nombre.

en général, la façon de le faire est avec codes de contrôle terminal . C'est un cas particulièrement simple, pour lequel vous n'avez besoin que d'un caractère spécial: U+000D CARRIAGE RETURN, qui est écrit '\r' en Python (et beaucoup d'autres langues). Voici un exemple complet basé sur votre code:

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

certaines choses à ce sujet qui peuvent être surprenantes:

  • Le \r va au début de la chaîne de sorte que, lorsque le programme est en cours d'exécution, le curseur sera toujours d'après le nombre. Ce n'est pas seulement esthétique: certains émulateurs de terminaux deviennent très confus si vous le faites dans l'autre sens.
  • si vous n'incluez pas la dernière ligne, alors après que le programme se termine, votre interpréteur de commandes affichera son prompt en haut de ce nombre.
  • le stdout.flush est nécessaire sur certains systèmes, ou vous n'obtiendrez aucune sortie. D'autres systèmes peuvent ne pas l'exiger, mais il ne fait pas de mal.

si vous constatez que cela ne fonctionne pas, la première chose que vous devez soupçonner est que votre émulateur de terminal est bogué. Le programme vtttest peut vous aider à le tester.

vous pouvez remplacer le stdout.write par un print déclaration mais je préfère ne pas mélanger print avec l'utilisation directe des objets de fichier.

138
répondu zwol 2012-08-31 19:04:08

utilisez print item, pour faire la déclaration d'impression omettre la nouvelle ligne.

en Python 3, c'est print(item, end=" ") .

si vous voulez que chaque nombre s'affiche au même endroit, utilisez par exemple (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, c'est un peu plus compliqué; ici vous devez tirer la chasse d'eau sys.stdout ou il n'imprimera rien jusqu'à ce que la boucle soit terminée:

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()
44
répondu Tim Pietzcker 2010-07-14 20:16:55

comme les autres exemples,

J'utilise une approche similaire, mais au lieu de passer du temps de calcul de la dernière longueur de sortie, etc,

j'utilise simplement le code ANSI escapes pour revenir au début de la ligne et puis effacer toute la ligne avant d'imprimer ma sortie de statut actuel.

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()

pour utiliser dans votre boucle d'itération vous appelleriez juste quelque chose comme:

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

voir plus ici

15
répondu Matthew 2013-08-19 03:37:17

vous pouvez ajouter une virgule à votre déclaration d'impression pour imprimer un espace au lieu d'une nouvelle ligne dans chaque itération:

print item,

alternativement, si vous utilisez Python 2.6 ou plus tard, vous pouvez utiliser la nouvelle fonction d'impression, qui vous permettrait de spécifier que même un espace ne doit pas venir à la fin de chaque élément imprimé (ou vous permettre de spécifier quelle fin vous voulez):

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

Enfin, vous pouvez écrire directement à la norme sortie en l'important à partir du module sys, qui renvoie un objet ressemblant à un fichier:

from sys import stdout
...
stdout.write( str(item) )
13
répondu Eli Courtwright 2010-07-14 19:08:03

changement

print item

à

print "3[K", item, "\r",
sys.stdout.flush()
  • "\033[K" efface à la fin de la ligne
  • \r, retourne au début de la ligne
  • l'énoncé flush s'assure qu'il apparaît Immédiatement de sorte que vous obtenez la sortie en temps réel.
9
répondu Brooks 2015-07-14 21:37:18

je pense qu'une simple jointure devrait fonctionner:

nl = []
for x in range(1,10):nl.append(str(x))
print ' '.join(nl)
5
répondu xortion 2012-09-20 17:54:21

"Par la manière...... Comment le rafraîchir à chaque fois pour qu'il imprime mi dans un endroit juste changer le nombre."

c'est un sujet délicat. Ce que zack a suggéré (sortie des codes de commande de la console ) est une façon d'y parvenir.

vous pouvez utiliser (n)malédictions, mais cela fonctionne principalement sur *nixes.

sur Windows (et voici une partie intéressante) qui est rarement mentionné (Je ne comprends pas pourquoi), vous pouvez utiliser Fixations Python à WinAPI ( http://sourceforge.net/projects/pywin32 / aussi avec ActivePython par défaut) - ce n'est pas si dur et fonctionne bien. Voici un petit exemple:

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 )

ou, si vous voulez utiliser print (énoncé ou Fonction, Pas de différence):

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 module vous permet de faire beaucoup plus de choses intéressantes avec Windows console... Je ne suis pas un grand fan de WinAPI, mais récemment j'ai réalisé qu'au moins la moitié de mon antipathie envers elle a été causée par l'écriture de code WinAPI dans les fixations C - pythonic sont beaucoup plus faciles à utiliser.

toutes les autres réponses sont grandes et pythoniques, bien sûr, mais... Que faire si je voulais imprimer sur la ligne précédent ? Ou écrire du texte multiligne, de l'effacer et d'écrire les mêmes lignes de nouveau? Ma solution rend cela possible.

3
répondu cji 2010-07-14 20:32:45

une Autre réponse que j'utilise sur les 2,7 où je suis juste l'impression d'une "."chaque fois qu'une boucle s'exécute (pour indiquer à l'utilisateur que les choses sont encore en cours d'exécution), c'est:

print "\b.",

il imprime le"."les caractères sans espaces entre chaque. Il semble un peu mieux et fonctionne plutôt bien. Le \b est un caractère d'arrière-plan pour ceux qui se demandent.

3
répondu copeland3300 2016-01-14 19:42:48

pour faire les nombres s'écraser, vous pouvez faire quelque chose comme ceci:

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

Qui devrait fonctionner aussi longtemps que le numéro est imprimé sur la première colonne.

EDIT: Voici une version qui fonctionnera même si elle n'est pas imprimée dans la première colonne.

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

je dois noter que ce code a été testé et fonctionne très bien en Python 2.5 sur Windows, dans la console WIndows. Selon certains autres, les bouffées de chaleur de stdout peut être nécessaire pour voir les résultats. YMMV.

2
répondu Adam Crossland 2010-07-14 20:30:30
In [9]: print?
Type:           builtin_function_or_method
Base Class:     <type 'builtin_function_or_method'>
String Form:    <built-in function print>
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.
1
répondu gtrak 2010-07-14 19:06:57
for i in xrange(1,100):
  print i,
1
répondu eruciform 2010-07-14 19:08:44

pour Python 2.7

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

pour Python 3

for x in range(0, 3):
    print(x, end=" ")
1
répondu Adnan Ghaffar 2015-12-17 13:03:14

si vous voulez juste imprimer les nombres, vous pouvez éviter la boucle.

# 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 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 tot 21.1986929975 ms

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 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 to 491.466823551 ms

0
répondu Mahmoud Kassem 2010-07-14 20:50:50

La meilleure façon d'y parvenir est d'utiliser le \r caractère

essayez le code ci-dessous:

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
0
répondu vitiral 2014-12-22 20:24:31

en Python 3 vous pouvez le faire de cette façon:

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

sorties:

1 2 3 4 5 6 7 8 9 

Tuple: vous pouvez faire la même chose avec un tuple:

tup = (1,2,3,4,5)

for n in tup:
    print(n, end = " - ")

sorties:

1 - 2 - 3 - 4 - 5 - 

un autre exemple:

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

sorties:

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

vous pouvez même déballer votre tuple comme ceci:

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)   

sorties:

1 2
A B
3 4
Cat Dog

une autre variante:

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

sorties:

1
2


A
B


3
4


Cat
Dog
0
répondu Stryker 2018-04-13 16:28:32

Pour 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)
-1
répondu GEEK 2016-11-28 10:20:45