it-swarm.com.de

Dynamisch in einer Zeile drucken

Ich möchte mehrere Aussagen treffen, die Standardausgabe ergeben, ohne dass Zeilenumbrüche zwischen den Anweisungen erscheinen.

Angenommen, ich habe Folgendes:

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

Das Ergebnis ist:

1
2
3
4
.
.
.

Wie bekomme ich das stattdessen aussehen:

1 2 3 4 5 ...

Ist es noch besser, die einzelne Nummer over die letzte Nummer zu drucken, so dass jeweils nur eine Nummer auf dem Bildschirm angezeigt wird?

255
Pol

print item ändern in:

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

Wenn Sie die Daten dynamisch drucken möchten, verwenden Sie folgende Syntax:

  • print(item, sep=' ', end='', flush=True) in Python 3
421
ewall

Übrigens ...... Wie man es jedes Mal auffrischt, so dass mi an einem Ort gedruckt wird, ändert man einfach die Nummer.

Im Allgemeinen erfolgt dies mit Terminal-Steuercodes . Dies ist ein besonders einfacher Fall, für den Sie nur ein Sonderzeichen benötigen: U + 000D CARRIAGE RETURN, das in Python (und vielen anderen Sprachen) '\r' geschrieben ist. Hier ist ein vollständiges Beispiel, das auf Ihrem Code basiert:

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

Einige Dinge dazu können überraschend sein:

  • Der \r steht am Anfang des Strings, so dass der Cursor während des Programmablaufs immer hinter der Zahl steht. Dies ist nicht nur kosmetisch: Einige Terminalemulatoren werden sehr verwirrt, wenn Sie es umgekehrt machen.
  • Wenn Sie die letzte Zeile nicht angeben, druckt Ihre Shell nach Beendigung des Programms die Eingabeaufforderung über die Nummer.
  • Der stdout.flush ist auf einigen Systemen erforderlich, oder Sie erhalten keine Ausgabe. Andere Systeme benötigen dies möglicherweise nicht, aber es schadet nicht.

Wenn Sie feststellen, dass dies nicht funktioniert, sollten Sie zunächst vermuten, dass Ihr Terminalemulator fehlerhaft ist. Das Programm vttest kann Ihnen beim Testen helfen.

Sie könnten stdout.write durch eine print-Anweisung ersetzen, aber ich möchte print nicht mit direkter Verwendung von Dateiobjekten mischen.

141
zwol

Verwenden Sie print item,, damit die Druckaussage den Zeilenumbruch weglässt.

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

Wenn jede Zahl an derselben Stelle angezeigt werden soll, verwenden Sie beispielsweise (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),

In Python 3 ist es etwas komplizierter; Hier müssen Sie sys.stdout leeren, oder es wird nichts gedruckt, bis die Schleife beendet ist:

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()
47
Tim Pietzcker

Wie die anderen Beispiele
Ich benutze einen ähnlichen Ansatz, aber anstatt Zeit zu verwenden, um die letzte Ausgabelänge zu berechnen, usw. 

Ich verwende einfach ANSI-Code-Escape-Zeichen, um zum Anfang der Zeile zurückzukehren und die gesamte Zeile zu löschen, bevor meine aktuelle Statusausgabe gedruckt wird.

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

Um es in Ihrer Iterationsschleife zu verwenden, würden Sie einfach so etwas nennen:

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

Mehr sehen hier

16
Matthew

Sie können Ihrer Druckanweisung ein nachfolgendes Komma hinzufügen, um in jeder Iteration ein Leerzeichen anstelle eines Zeilenumbruchs zu drucken:

print item,

Wenn Sie Python 2.6 oder höher verwenden, können Sie alternativ die neue Druckfunktion verwenden, mit der Sie angeben können, dass nicht einmal ein Leerzeichen am Ende jedes gedruckten Elements erscheinen soll (oder Sie können angeben, an welchem ​​Ende Sie sich befinden) wollen):

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

Schließlich können Sie direkt in die Standardausgabe schreiben, indem Sie sie aus dem sys-Modul importieren, das ein dateiähnliches Objekt zurückgibt:

from sys import stdout
...
stdout.write( str(item) )
14
Eli Courtwright

veränderung

print item

zu

print "\033[K", item, "\r",
sys.stdout.flush()
  • "\ 033 [K" löscht bis zum Ende der Zeile 
  • das\r kehrt zum Anfang der Zeile zurück 
  • die Flush-Anweisung stellt sicher, dass sie sofort angezeigt wird, sodass Sie Echtzeitausgabe erhalten.
10
Brooks

Ich denke, ein einfacher Join sollte funktionieren:

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

"Übrigens ...... Wie man es jedes Mal auffrischt, so dass mi an einem Ort gedruckt wird, ändert man einfach die Nummer."

Es ist wirklich ein kniffliges Thema. Der Vorschlag von zack (Ausgabe von Steuerungscodes für die Konsole) ist eine Möglichkeit, dies zu erreichen.

Sie können (n) Flüche verwenden, aber das funktioniert hauptsächlich bei * Nixen.

Unter Windows (und hier wird ein interessanter Teil genannt), der selten erwähnt wird (ich kann nicht verstehen, warum), können Sie Python-Bindings für WinAPI verwenden ( http://sourceforge.net/projects/pywin32/ ). Standardmäßig auch mit ActivePython ) - es ist nicht so schwer und funktioniert gut. Hier ist ein kleines Beispiel:

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 )

Oder, wenn Sie print verwenden möchten (Anweisung oder Funktion, kein Unterschied):

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 )

Mit dem win32console-Modul können Sie viele weitere interessante Dinge mit der Windows-Konsole tun ... Ich bin kein großer Fan von WinAPI, aber vor kurzem wurde mir klar, dass mindestens die Hälfte meiner Abneigung gegen WinAPI durch das Schreiben von WinAPI-Code in C-Pythonic-Bindungen verursacht wurde sind viel einfacher zu bedienen.

Alle anderen Antworten sind natürlich großartig und natürlich Pythonic, aber ... Was wäre, wenn ich in der vorherigen Zeile drucken wollte? Oder mehrzeiligen Text schreiben, dann löschen und dieselben Zeilen erneut schreiben? Meine Lösung macht das möglich.

3
cji

Eine andere Antwort, die ich unter 2.7 verwende, wo ich nur ein "." Jedes Mal, wenn eine Schleife ausgeführt wird (um dem Benutzer anzuzeigen, dass die Dinge noch laufen), lautet Folgendes

print "\b.",

Es druckt das "." Zeichen ohne Leerzeichen. Es sieht etwas besser aus und funktioniert ziemlich gut. Das\b ist ein Rückschrittzeichen für diejenigen, die sich fragen.

3
copeland3300

Damit sich die Zahlen gegenseitig überschreiben, können Sie Folgendes tun:

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

Das sollte funktionieren, solange die Nummer in der ersten Spalte steht.

EDIT: Hier ist eine Version, die auch dann funktioniert, wenn sie nicht in der ersten Spalte gedruckt wird.

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

Ich sollte beachten, dass dieser Code in Python 2.5 unter Windows in der Windows-Konsole getestet wurde und einwandfrei funktioniert. In einigen Fällen kann es erforderlich sein, stdout zu spülen, um die Ergebnisse zu sehen. YMMV.

2
Adam Crossland

für Python 2.7

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

für Python 3

for x in range(0, 3):
    print(x, end=" ")
1
Adnan Ghaffar
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
gtrak
for i in xrange(1,100):
  print i,
1
eruciform

In Python 3 können Sie dies folgendermaßen tun:

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

Ausgänge:

1 2 3 4 5 6 7 8 9 

Tuple: Sie können dasselbe mit einem Tuple machen:

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

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

Ausgänge:  

1 - 2 - 3 - 4 - 5 - 

Ein anderes Beispiel:

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

Ausgänge:

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

Du kannst dein Tuple sogar so auspacken:

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)   

Ausgänge:

1 2
A B
3 4
Cat Dog

eine andere 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')

Ausgänge:

1
2


A
B


3
4


Cat
Dog
0
Stryker

Dies erreichen Sie am besten mit dem Zeichen \r

Probieren Sie einfach den folgenden Code aus:

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
vitiral

So viele komplizierte Antworten. Wenn Sie python 3 haben, setzen Sie \r einfach am Anfang des Ausdrucks ein und fügen Sie end='', flush=True hinzu:

import time

for i in range(10):
    print(f'\r{i} foo bar', end='', flush=True)
    time.sleep(0.5)

Dies schreibt 0 foo bar, dann 1 foo bar usw. an Ort und Stelle.

0
Hugh Perkins

Wenn Sie nur die Zahlen drucken möchten, können Sie die Schleife vermeiden.

# 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 28 28 30 30 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 73 73 75 76 77 78 79 80 83 83 85 85 88 88 90 90 92 93 94 95 96 97 98 99 100 dauerte 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 28 28 30 30 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 73 73 75 76 78 78 80 80 83 83 85 85 88 88 90 90 92 93 94 95 96 97 98 99 100 dauerte 491.466823551ms

0
Mahmoud Kassem