关于python:动态打印一行

Print in one line dynamically

我想做几个语句,在语句之间不看到换行的情况下给出标准输出。

具体来说,假设我有:

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

结果是:

1
2
3
4
5
6
7
1
2
3
4
.
.
.

如何让它看起来像:

1
1 2 3 4 5 ...

更好的是,是否可以在最后一个数字上打印单个数字,这样一次屏幕上只有一个数字?


print item改为:

  • python 2.7中的print item,
  • python 3中的print(item, end="")

如果要动态打印数据,请使用以下语法:

  • python 3中的print(item, sep=' ', end='', flush=True)


By the way...... How to refresh it every time so it print mi in one place just change the number.

一般来说,实现这一点的方法是使用终端控制代码。这是一个特别简单的例子,您只需要一个特殊的字符:u+000d回车,它是用python(和许多其他语言)编写的'
'
。下面是一个基于您的代码的完整示例:

1
2
3
4
5
6
7
8
9
from sys import stdout
from time import sleep
for i in range(1,20):
    stdout.write("
%d"
% i)
    stdout.flush()
    sleep(1)
stdout.write("
"
) # move the cursor to the next line

这方面的一些事情可能会令人惊讶:


  • 位于字符串的开头,以便在程序运行时,光标始终位于数字之后。这不仅仅是表面化的:如果换一种方式,一些终端仿真器会非常困惑。
  • 如果不包括最后一行,那么在程序终止后,shell将在数字的顶部打印其提示。
  • 在某些系统中,stdout.flush是必需的,否则您将无法获得任何输出。其他系统可能不需要它,但它不会造成任何伤害。

如果您发现这不起作用,首先应该怀疑的是您的终端模拟器有问题。VTTEST程序可以帮助您测试它。

您可以用print语句替换stdout.write,但我不喜欢将print与直接使用文件对象混合使用。


使用print item,使print语句省略换行符。

在python 3中,它是print(item, end="")

如果希望每个数字都显示在同一位置,请使用例如(python 2.7):

1
2
3
4
5
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,否则在循环完成之前,它不会打印任何内容:

1
2
3
4
5
6
7
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()


像其他例子一样,我使用了类似的方法,但没有花时间计算出最后的输出长度等,

我只需使用ansi代码转义移回行首,然后在打印当前状态输出之前清除整行。

1
2
3
4
5
6
7
8
import sys

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

要在迭代循环中使用,您只需调用如下内容:

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

在此处查看更多信息


您可以在print语句中添加尾随逗号,以在每次迭代中打印空格而不是换行符:

1
print item,

或者,如果您使用的是python 2.6或更高版本,则可以使用新的print函数,该函数允许您指定即使是一个空格也不应出现在正在打印的每个项目的末尾(或允许您指定所需的任何结尾):

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

最后,通过从sys模块导入标准输出,可以直接写入标准输出,该模块返回类似文件的对象:

1
2
3
from sys import stdout
...
stdout.write( str(item) )


改变

1
print item

1
2
3
print"\033[K", item,"
"
,
sys.stdout.flush()

  • "33[K"清除到行尾
  • 返回到行首
  • flush语句确保它立即显示,以便获得实时输出。


我认为简单的连接应该有效:

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


我在2.7上使用的另一个答案是,每次循环运行时(向用户指示事物仍在运行),都会打印出一个".",如下所示:

1
print"\b.",

它打印"."字符,每个字符之间没有空格。它看起来好一点,效果也不错。对于那些好奇的人来说是退格字符。


"顺便说一下……如何每次刷新它,以便它在一个地方打印mi,只需更改数字即可。"

这真是个棘手的话题。扎克建议(输出控制台控制代码)是实现这一点的一种方法。

你可以使用诅咒,但这主要适用于*尼克斯。

在Windows上(这里有一个有趣的部分),这是很少提到的(我不明白为什么),您可以使用到winapi的python绑定(http://sourceforge.net/projects/pywin32/,默认情况下也可以与activepython一起使用)——这并不难,而且工作得很好。下面是一个小例子:

1
2
3
4
5
6
7
8
9
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(语句或函数,没有区别):

1
2
3
4
5
6
7
8
9
10
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,但最近我意识到,我对它的反感至少有一半是因为用c-python绑定编写winapi代码更容易使用。

当然,所有其他的答案都很好,而且是Python式的,但是……如果我想在上一行打印怎么办?或者写多行文字,然后清除它,再写相同的行?我的解决方案使这成为可能。


要使数字相互覆盖,可以执行如下操作:

1
2
3
for i in range(1,100):
    print"
"
,i,

只要数字打印在第一列中就可以了。

编辑:这是一个即使没有在第一列中打印也能正常工作的版本。

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

我应该注意到这段代码是经过测试的,在Windows控制台的python 2.5中运行得很好。另一些人认为,可能需要刷新stdout才能看到结果。YMMV。


对于python 2.7

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

对于python 3

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


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


1
2
3
4
5
6
7
8
9
10
11
12
13
14
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='
'
, 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.


在Python3中,您可以这样做:

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

输出:

1
1 2 3 4 5 6 7 8 9

tuple:可以对tuple执行相同的操作:

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

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

输出:

1
1 - 2 - 3 - 4 - 5 -

另一个例子:

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

输出:

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

您甚至可以这样解包tuple:

1
2
3
4
5
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
3
4
1 2
A B
3 4
Cat Dog

另一个变化:

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

输出:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
1
2


A
B


3
4


Cat
Dog


实现这一点的最佳方法是使用
字符

只需尝试以下代码:

1
2
3
4
5
6
import time
for n in range(500):
  print(n, end='
'
)
  time.sleep(0.01)
print()  # start new line so most recently printed number stays

如果您只想打印数字,可以避免循环。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
# 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
'
.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('
took {0}ms
'
.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 30 31 32 33 34 35 36 37 39 40 41 42 43 44 45 46 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 68 69 70 71 72 73 74 75 76 78 79 80 81 82 83 85 86 87 89 90 91 92 93 95 96 97 98 99 100用了21.198692975毫秒

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 30 31 32 33 34 35 36 37 39 40 41 42 43 44 45 46 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 68 69 70 71 72 73 74 75 76 78 79 80 81 82 83 85 86 87 89 90 91 92 93 95 96 97 98 99 100取491.466823551ms


对于python(2.7)

1
2
3
4
5
6
 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

Python3

1
2
3
4
5
6
 l=""
        for item in range(1,100):
            item=str(item)
            l=l+""+item
            l.lstrip()
        print(l)