我想做几个语句,给出标准输出,而不看到换行之间的语句。
具体来说,假设我有:
for item in range(1,100):
print item
结果是:
1
2
3
4
.
.
.
如何让它看起来像:
1 2 3 4 5 ...
更好的是,是否可以将单个数字打印在最后一个数字之上,这样一次只有一个数字出现在屏幕上?
我想做几个语句,给出标准输出,而不看到换行之间的语句。
具体来说,假设我有:
for item in range(1,100):
print item
结果是:
1
2
3
4
.
.
.
如何让它看起来像:
1 2 3 4 5 ...
更好的是,是否可以将单个数字打印在最后一个数字之上,这样一次只有一个数字出现在屏幕上?
使用print item,使print语句省略换行符。
在python3中,它是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中,这有点复杂;这里你需要刷新系统。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()
将打印项更改为:
在Python 2.7中,打印项 print(item, end=" "
如果你想动态打印数据,请使用以下语法:
打印(item, sep=' ', end= ", flush=True
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.
你可以在你的print语句中添加一个尾随逗号,在每次迭代中打印一个空格而不是换行符:
print item,
或者,如果你使用的是Python 2.6或更高版本,你可以使用新的print函数,它允许你指定甚至不应该在打印的每一项的结尾出现空格(或者允许你指定任何你想要的结尾):
from __future__ import print_function
...
print(item, end="")
最后,你可以通过从sys模块导入标准输出直接写入标准输出,它会返回一个类文件对象:
from sys import stdout
...
stdout.write( str(item) )
为了让数字相互覆盖,你可以这样做:
for i in range(1,100):
print "\r",i,
只要把数字打印在第一列,这就可以工作。
编辑: 这里有一个版本,即使没有打印在第一列,也可以工作。
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中,在Windows控制台中工作得很好。根据其他一些方法,可能需要刷新stdout才能查看结果。YMMV。
顺便说一下......如何每次刷新它,所以它打印mi在一个地方,只是改变数字。
一般来说,这样做的方法是使用终端控制代码。这是一个特别简单的情况,你只需要一个特殊的字符:U+000D CARRIAGE RETURN,它在Python(和许多其他语言)中被写成'\r'。下面是一个基于你的代码的完整示例:
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位于字符串的开头,以便在程序运行时,光标始终位于数字后面。这不仅仅是表面上的:如果你反过来做,一些终端模拟器会非常混乱。 如果您不包括最后一行,那么在程序终止后,shell将在数字上方打印提示符。 stdout。在某些系统上Flush是必要的,否则将得不到任何输出。其他系统可能不需要它,但它不会造成任何损害。
如果你发现这不起作用,你应该怀疑的第一件事是你的终端模拟器有bug。vttest程序可以帮助你测试它。
可以替换stdout。写与打印语句,但我不喜欢混合打印与直接使用文件对象。
“顺便说一下......如何刷新它,所以它打印mi在一个地方,只要改变数字。”
这真的是个棘手的话题。zack所建议的(输出控制台控制代码)是实现这一目标的一种方法。
你可以使用(n)诅咒,但这主要适用于*nix。
在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的忠实粉丝,但最近我意识到我对它的反感至少有一半是由用C语言编写WinAPI代码引起的——python绑定更容易使用。
当然,所有其他的答案都很棒,而且很深奥,但是……如果我想打印上一行呢?或者写多行文本,而不是清除它,再写相同的行?我的解决方案使之成为可能。
如果你只是想打印数字,你可以避免循环:
# 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
took 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 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
took 491.466823551ms
和其他例子一样, 我使用类似的方法,但不是花时间计算最后的输出长度,等等,
我简单地使用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
点击这里查看更多信息
我认为一个简单的连接应该工作:
nl = []
for x in range(1,10):nl.append(str(x))
print ' '.join(nl)
实现这一点的最佳方法是使用\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
改变
print item
to
print "\033[K", item, "\r",
sys.stdout.flush()
“\033[K”清除到行尾 \r返回行首 flush语句确保它立即显示,以便获得实时输出。
for Python 2.7
for x in range(0, 3):
print x,
for python3
for x in range(0, 3):
print(x, end=" ")
我在2.7中使用的另一个答案是,每当循环运行时,我只是打印出一个“。”(向用户表明事情仍在运行):
print "\b.",
它输出“。”字符,每个字符之间没有空格。它看起来好一点,工作得很好。\b是一个退格字符。
在Python 3中,你可以这样做:
for item in range(1,10):
print(item, end =" ")
输出:
1 2 3 4 5 6 7 8 9
Tuple:你可以对Tuple做同样的事情:
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
这么多复杂的答案。如果你使用的是python3,只需在打印的开头放置\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等。
对于那些像我一样挣扎的人,我提出了以下似乎在python 3.7.4和3.5.2中都可以工作的方法。
I expanded the range from 100 to 1,000,000 because it runs very fast and you may not see the output. This is because one side effect of setting end='\r' is that the final loop iteration clears all of the output. A longer number was needed to demonstrate that it works. This result may not be desirable in all cases, but was fine in mine, and OP didn't specify one way or another. You could potentially circumvent this with an if statement that evaluates the length of the array being iterated over, etc. The key to get it working in my case was to couple the brackets "{}" with .format(). Otherwise, it didn't work.
以下应按原样工作:
#!/usr/bin/env python3
for item in range(1,1000000):
print("{}".format(item), end='\r', flush=True)
for item in range(1,100):
if item==99:
print(item,end='')
else:
print (item,end=',')
输出: 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
或者更简单:
import time
a = 0
while True:
print (a, end="\r")
a += 1
time.sleep(0.1)
End ="\r"将覆盖第一次打印的开头[0:]。
如果您希望它作为字符串,您可以使用
number_string = ""
for i in range(1, 100):
number_string += str(i)
print(number_string)
注意:我之所以指出这个解决方案,是因为如果下一次打印的长度小于前一次打印的长度,我所见过的大多数其他解决方案都不起作用。
如果您知道要删除什么,并且可以使用全局变量,那么只需用空格覆盖最后一行。
在打印之前,将字符串的长度存储为' n '。 打印它,但以' \r '结尾(它返回行首)。 下次,在打印信息之前,在该行上打印“n”个空格。
_last_print_len = 0
def reprint(msg, finish=False):
global _last_print_len
# Ovewrites line with spaces.
print(' '*_last_print_len, end='\r')
if finish:
end = '\n'
# If we're finishing the line, we won't need to overwrite it in the next print.
_last_print_len = 0
else:
end = '\r'
# Store len for the next print.
_last_print_len = len(msg)
# Printing message.
print(msg, end=end)
例子:
for i in range(10):
reprint('Loading.')
time.sleep(1)
reprint('Loading..')
time.sleep(1)
reprint('Loading...')
time.sleep(1)
for i in range(10):
reprint('Loading.')
time.sleep(1)
reprint('Loading..')
time.sleep(1)
reprint('Loading...', finish=True)
time.sleep(1)