动态地在一行中打印[重复]
- 2024-12-02 08:41:00
- admin 原创
- 161
问题描述:
我想制作几个提供标准输出的语句,而语句之间不会出现换行符。
具体来说,假设我有:
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,它是`'
'`用 Python(和许多其他语言)编写的。以下是基于您的代码的完整示例:
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程序可以帮助你测试它。
stdout.write
您可以用语句替换print
,但我不喜欢print
直接使用文件对象。
解决方案 3:
用于print item,
使打印语句省略换行符。
在 Python 3 中,它是print(item, end=" ")
。
如果希望每个数字显示在同一个位置,例如使用(Python 2.7):
to = 20
digits = len(str(to - 1))
delete = "" * (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 = "" * (digits)
for i in range(to):
print("{0}{1:{2}}".format(delete, i, digits), end="")
sys.stdout.flush()
解决方案 4:
与其他示例一样,
我使用了类似的方法,但不是花时间计算最后的输出长度等,
我只需使用 ANSI 代码转义即可返回到行首,然后在打印当前状态输出之前清除整行。
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()
要在迭代循环中使用,只需调用类似如下的函数:
x = 1
for f in fileList:
ProcessFile(f)
output = "File number %d completed." % x
Printer(output)
x += 1
更多详情请见此处
解决方案 5:
这么多复杂的答案。如果你有 python 3,只需将其放在`打印的开头,然后添加
end='', flush=True`:
import time
for i in range(10):
print(f'
{i} foo bar', end='', flush=True)
time.sleep(0.5)
这将在原地写入0 foo bar
,然后等等。1 foo bar
解决方案 6:
您可以在打印语句中添加尾随逗号,以便在每次迭代中打印空格而不是换行符:
print item,
或者,如果您使用的是 Python 2.6 或更高版本,则可以使用新的打印函数,该函数允许您指定在打印的每个项目的末尾都不应有空格(或允许您指定您想要的任何结尾):
from __future__ import print_function
...
print(item, end="")
最后,您可以通过从 sys 模块导入直接写入标准输出,该模块返回一个类似文件的对象:
from sys import stdout
...
stdout.write( str(item) )
解决方案 7:
改变
print item
到
print "[K", item, "
",
sys.stdout.flush()
“\033[K” 清除至行尾
\r,返回到行首
flush 语句确保它立即显示,以便您获得实时输出。
解决方案 8:
我在 2.7 上使用的另一个答案是,每次循环运行时我都会打印出一个“。”(向用户表明事情仍在运行),这是:
print ".",
它打印“.”字符,每个字符之间没有空格。它看起来更好一些,并且运行良好。对于那些想知道的人来说,\b 是一个退格符。
解决方案 9:
我认为一个简单的连接应该可以起作用:
nl = []
for x in range(1,10):nl.append(str(x))
print ' '.join(nl)
解决方案 10:
为了使数字互相覆盖,您可以执行以下操作:
for i in range(1,100):
print "
",i,
只要在第一列打印数字,这就应该有效。
编辑:这是一个即使没有打印在第一列也可以工作的版本。
prev_digits = -1
for i in range(0,1000):
print("%s%d" % (""*(prev_digits + 1), i)),
prev_digits = len(str(i))
我应该指出,此代码已在 Windows 上的 Python 2.5 中在 Windows 控制台中测试过,运行良好。根据其他人的说法,可能需要刷新 stdout 才能看到结果。YMMV。
解决方案 11:
“顺便问一下……每次如何刷新它以便它在一个地方打印 mi 只需更改数字即可。”
这确实是一个棘手的问题。zack建议的(输出控制台控制代码)是实现此目的的一种方法。
您可以使用 (n)curses,但它主要在 *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 的忠实粉丝,但最近我意识到我对它的反感至少有一半是由于用 C 编写 WinAPI 代码引起的——pythonic 绑定更易于使用。
当然,其他所有答案都很棒,而且很 Pythonic,但是...如果我想在前一行打印怎么办?或者写多行文本,然后清除它并再次写相同的行?我的解决方案使这成为可能。
解决方案 12:
对于 Python 2.7
for x in range(0, 3):
print x,
对于 Python 3
for x in range(0, 3):
print(x, end=" ")
解决方案 13:
在 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('
')
输出:
1
2
A
B
3
4
Cat
Dog
解决方案 14:
对于那些像我一样苦苦挣扎的人,我想出了下面的方法,它似乎在 python 3.7.4 和 3.5.2 中都有效。
我将范围从 100 扩大到 1,000,000,因为它运行速度非常快,您可能看不到输出。这是因为设置的一个副作用`end='
'是最后的循环迭代会清除所有输出。需要更长的数字来证明它有效。这个结果可能并非在所有情况下都令人满意,但对我来说很好,而且 OP 没有指定一种或另一种方式。您可以使用 if 语句来评估正在迭代的数组的长度等来规避这个问题。在我的情况下,让它工作的关键是将括号
"{}"与结合起来
.format()`。否则,它就不起作用了。
下面应该按原样工作:
#!/usr/bin/env python3
for item in range(1,1000000):
print("{}".format(item), end='
', flush=True)
解决方案 15:
或者更简单:
import time
a = 0
while True:
print (a, end="
")
a += 1
time.sleep(0.1)
`end="
"`将从第一个打印的开头 [0:] 覆盖。
解决方案 16:
注意:我指出这个解决方案是因为如果下一个打印的长度小于前一个打印的长度,那么我见过的大多数其他解决方案都不起作用。
如果您知道要删除的内容,并且可以承受全局变量,则只需用空格覆盖最后一行。
打印之前,将字符串的长度存储为“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='
')
if finish:
end = '
'
# If we're finishing the line, we won't need to overwrite it in the next print.
_last_print_len = 0
else:
end = '
'
# 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)
解决方案 17:
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.
解决方案 18:
打印语句末尾的逗号省略了新行。
for i in xrange(1,100):
print i,
但这不会覆盖。
解决方案 19:
实现此目的的最佳方法是使用`
`角色
尝试下面的代码:
import time
for n in range(500):
print(n, end='
')
time.sleep(0.01)
print() # start new line so most recently printed number stays
解决方案 20:
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
解决方案 21:
如果您只想打印数字,则可以避免循环:
# 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 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
解决方案 22:
如果你想要它作为一个字符串,你可以使用
number_string = ""
for i in range(1, 100):
number_string += str(i)
print(number_string)