Печать в одной строке динамически

Я хотел бы сделать несколько операторов, которые дают стандартный вывод, не видя новых строк между операторами.

В частности, предположим, что у меня есть:

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

Результат:

1
2
3
4
.
.
.

Как получить это, чтобы выглядеть следующим образом:

1 2 3 4 5 ...

Еще лучше, можно ли напечатать одиночное число по последнему номеру, так что на экране одновременно отображается только один номер?

Ответ 1

Измените print item на:

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

Если вы хотите динамически печатать данные, используйте следующий синтаксис:

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

Ответ 2

Кстати... Как обновлять его каждый раз, чтобы он печатал mi в одном месте, просто изменяйте число.

В общем, способ сделать это с терминальными управляющими кодами. Это особенно простой случай, для которого вам нужен только один специальный символ: U + 000D CARRIAGE RETURN, который записывается '\r' в Python (и многие другие языки). Вот полный пример, основанный на вашем коде:

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

Некоторые вещи об этом могут быть удивительными:

  • \r идет в начале строки, так что, пока программа запущена, курсор всегда будет после номера. Это не просто косметика: некоторые эмуляторы терминала очень запутаны, если вы делаете это наоборот.
  • Если вы не включили последнюю строку, то после завершения программы ваша оболочка напечатает приглашение поверх номера.
  • stdout.flush необходим для некоторых систем, или вы не получите никакого вывода. Другие системы могут не требовать этого, но это не наносит вреда.

Если вы обнаружите, что это не работает, первое, что вы должны подозревать, это то, что ваш эмулятор терминала неисправен. Программа vttest может помочь вам протестировать ее.

Вы можете заменить stdout.write на инструкцию print, но я предпочитаю не смешивать print с прямым использованием файловых объектов.

Ответ 3

Используйте print item,, чтобы оператор печати опускал новую строку.

В Python 3 это print(item, end=" ").

Если вы хотите, чтобы каждый номер отображался в одном месте, используйте, например, (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),

В Python 3 это немного сложнее; здесь вам нужно сбросить sys.stdout или ничего не напечатать до окончания цикла:

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

Ответ 4

Как и другие примеры,
Я использую подобный подход, но вместо того, чтобы тратить время на вычисление последней выходной длины и т.д.,

Я просто использую escape-коды ANSI, чтобы вернуться к началу строки, а затем очистить всю эту строку перед печатью текущего вывода состояния.

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

Чтобы использовать в своем цикле итерации, вы просто вызываете что-то вроде:

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

Подробнее см. здесь

Ответ 5

Вы можете добавить конечную запятую в оператор печати для печати пробела вместо новой строки на каждой итерации:

print item,

В качестве альтернативы, если вы используете Python 2.6 или новее, вы можете использовать новую функцию печати, которая позволит вам указать, что даже не должно быть места в конце каждого напечатанного элемента (или вы можете указать независимо от того, что вы хотите):

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

Наконец, вы можете напрямую написать стандартный вывод, импортировав его из модуля sys, который возвращает файл-подобный объект:

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

Ответ 6

изменить

print item

к

print "\033[K", item, "\r",
sys.stdout.flush()
  • "\ 033 [K" очищается до конца строки
  • the\r, возвращает начало строки
  • оператор flush гарантирует, что он будет отображаться немедленно, так что вы получите вывод в реальном времени.

Ответ 7

Я думаю, что простое соединение должно работать:

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

Ответ 8

Еще один ответ, который я использую в версии 2.7, где я просто распечатываю ".". каждый раз, когда цикл запускается (чтобы указать пользователю, что все еще выполняется), выполните следующее:

print "\b.",

Он печатает "." символы без пробелов между ними. Он выглядит немного лучше и работает очень хорошо. \B является символом обратного пространства для тех, кто задается вопросом.

Ответ 9

Чтобы числа переписывали друг друга, вы можете сделать что-то вроде этого:

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

Это должно работать до тех пор, пока число будет напечатано в первом столбце.

EDIT: Здесь версия, которая будет работать, даже если она не будет напечатана в первом столбце.

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

Я должен отметить, что этот код был протестирован и отлично работает в Python 2.5 на Windows, в консоли WIndows. По мнению некоторых других, для достижения результатов может потребоваться промывка stdout. YMMV.

Ответ 10

"Кстати... Как обновлять его каждый раз, чтобы он печатал mi в одном месте, просто изменяйте номер".

Это действительно сложная тема. Что предлагает zack (вывод управляющих кодов консоли), это один из способов достижения этого.

Вы можете использовать (n) проклятия, но это работает в основном на * nixes.

В Windows (и здесь идет интересная часть), которая редко упоминается (я не могу понять, почему) вы можете использовать привязки Python к WinAPI (http://sourceforge.net/projects/pywin32/ также с ActivePython по умолчанию) - это не так сложно и работает хорошо. Вот небольшой пример:

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 )

Или, если вы хотите использовать print (инструкция или функция, без разницы):

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 модуль позволяет вам делать еще много интересного с помощью консоли Windows... Я не большой поклонник WinAPI, но недавно я понял, что по крайней мере половина моей антипатии к ней была вызвана написанием кода WinAPI в C - питонические привязки гораздо проще в использовании.

Все остальные ответы велики и питоничны, но... Что делать, если я хотел напечатать на предыдущей строке? Или написать многострочный текст, чем очистить его и снова написать те же строки? Мое решение делает это возможным.

Ответ 11

для Python 2.7

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

для Python 3

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

Ответ 12

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.

Ответ 13

for i in xrange(1,100):
  print i,

Ответ 14

Так много сложных ответов. Если у вас есть Python 3, просто поместите \r в начале печати и добавьте к нему end='', flush=True:

import time

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

Это напишет 0 foo bar, затем 1 foo bar и т.д. на месте.

Ответ 15

Если вы просто хотите напечатать цифры, вы можете избежать цикла.

# 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 взял 21.1986929975мс

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 взял 491.466823551ms

Ответ 16

Лучший способ добиться этого - использовать символ \r

Просто попробуйте приведенный ниже код:

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

Ответ 17

В Python 3 вы можете сделать это следующим образом:

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

Выходы:

1 2 3 4 5 6 7 8 9 

Кортеж: вы можете сделать то же самое с кортежем:

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

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

Выходы:

1 - 2 - 3 - 4 - 5 - 

Другой пример:

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

Выходы:

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

Вы даже можете распаковать свой кортеж следующим образом:

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)   

Выходы:

1 2
A B
3 4
Cat Dog

другой вариант:

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

Выходы:

1
2


A
B


3
4


Cat
Dog

Ответ 18

просто напишите end = "" в выражении print()

например:

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

Ответ 19

Для 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)