374 votes

Impression dynamique sur une seule ligne

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

Plus précisément, supposons que je l'ai fait :

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

Le résultat est le suivant :

1
2
3
4
.
.
.

Comment faire pour que cela ressemble plutôt à.. :

1 2 3 4 5 ...

Mieux encore, est-il possible d'imprimer le seul nombre plus le dernier numéro, de sorte qu'un seul numéro soit affiché à l'écran à la fois ?

0 votes

559voto

ewall Points 10676

Changer print item à :

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

Si vous souhaitez imprimer les données de manière dynamique, utilisez la syntaxe suivante :

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

1 votes

De http://docs.python.org/reference/simple_stmts.html#print : > A '\n' est écrit à la fin, sauf si le caractère print se termine par une virgule. C'est la seule action possible si la déclaration ne contient que le mot-clé print .

5 votes

Pour information : print(item, end=" ") peut être utilisé dans Python2.7 en ajoutant 'from futur import print_function' au début du fichier.

3 votes

Mais flush ne fonctionne pas avec from __future__ import print_function malheureusement.

175voto

Zack Points 44583

Au fait...... Comment l'actualiser à chaque fois pour qu'il s'imprime au même endroit, il suffit de changer le numéro.

En général, la façon de procéder est la suivante codes de contrôle du terminal . Il s'agit d'un cas particulièrement simple, pour lequel un seul caractère spécial est nécessaire : U+000D CARRIAGE RETURN, qui s'écrit '\r' en Python (et dans de nombreux autres langages). 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

Il y a des choses qui peuvent être surprenantes à ce sujet :

  • En \r se place au début de la chaîne de manière à ce que, pendant l'exécution du programme, le curseur se trouve toujours après le numéro. Il ne s'agit pas seulement d'une question d'esthétique : certains émulateurs de terminaux sont très confus si vous procédez dans l'autre sens.
  • Si vous n'incluez pas la dernière ligne, après la fin du programme, l'interpréteur de commandes affichera son invite au-dessus du nombre.
  • En stdout.flush est nécessaire sur certains systèmes, sinon vous n'obtiendrez aucun résultat. D'autres systèmes peuvent ne pas l'exiger, mais cela ne fait aucun mal.

Si vous constatez que cela ne fonctionne pas, la première chose à soupçonner est que votre émulateur de terminal est défectueux. L'émulateur de terminal vttest peut vous aider à le tester.

Vous pouvez remplacer le stdout.write avec un print mais je préfère ne pas mélanger print avec l'utilisation directe d'objets de fichiers.

0 votes

Que signifie la fonction flush() ? Car cela fonctionne pour moi sans cette fonction !

2 votes

Normalement, les objets fichiers de Python accumulent des données afin de pouvoir les envoyer au système d'exploitation en gros morceaux. C'est ce que vous voulez pour accéder aux fichiers sur le disque, en général, mais cela interfère avec ce type de tâche. flush() force un fichier à envoyer ce qu'il contient au système d'exploitation. Je suis surpris que cela fonctionne pour vous sans cela -- cela ne fonctionnait pas pour moi jusqu'à ce que je l'ajoute.

0 votes

J'ai un système d'exploitation win32 et python 2.6. Quel est votre système d'exploitation ?

56voto

Tim Pietzcker Points 146308

Utilice print item, pour que l'instruction d'impression ne tienne pas compte de la nouvelle ligne.

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

Si vous voulez que tous les nombres s'affichent 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, il faut flusher sys.stdout ou il n'imprimera rien avant la fin de la boucle :

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

0 votes

En fait, il me semble que votre solution imprimera le même nombre d'espaces à chaque fois. Ainsi, si to est 20, il imprimera un espace supplémentaire lors de l'impression des chiffres 1..9. Ne devriez-vous pas calculer les chiffres à l'intérieur de la boucle et vous baser sur la valeur de i ?

0 votes

Il justifie le nombre à droite et supprime toujours tout. Je n'ai pas encore testé s'il est plus rapide de faire cela ou de calculer à chaque itération le nombre de chiffres à effacer.

0 votes

Ou bien, il faut se baser sur la valeur précédente de i pour tenir compte du changement du nombre de chiffres.

22voto

Matthew Points 158

Comme les autres exemples,
J'utilise une approche similaire, mais au lieu de passer du temps à calculer la longueur de la dernière sortie, etc,

J'utilise simplement les échappements de code ANSI pour revenir au début de la ligne, puis j'efface toute la ligne avant d'imprimer ma sortie d'état actuelle.

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 l'utiliser dans votre boucle d'itération, il vous suffit d'appeler quelque chose comme :

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

Plus d'informations ici

15voto

Eli Courtwright Points 53071

Vous pouvez ajouter une virgule de fin à votre instruction print pour imprimer un espace au lieu d'une nouvelle ligne à chaque itération :

print item,

Si vous utilisez Python 2.6 ou une version ultérieure, vous pouvez également utiliser la nouvelle fonction print, qui vous permet de spécifier qu'aucun espace ne doit figurer à la fin de chaque élément imprimé (ou vous permet de spécifier la fin de votre choix) :

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

Enfin, vous pouvez écrire directement sur la sortie standard en l'important du module sys, qui renvoie un objet de type fichier :

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

Prograide.com

Prograide est une communauté de développeurs qui cherche à élargir la connaissance de la programmation au-delà de l'anglais.
Pour cela nous avons les plus grands doutes résolus en français et vous pouvez aussi poser vos propres questions ou résoudre celles des autres.

Powered by:

X