Print in one line dynamically
Question:
I would like to make several statements that give standard output without seeing newlines in between statements.
Specifically, suppose I have:
for item in range(1,100):
print item
The result is:
1
2
3
4
.
.
.
How get this to instead look like:
1 2 3 4 5 ...
Even better, is it possible to print the single number over the last number, so only one number is on the screen at a time?
Answers:
Use print item,
to make the print statement omit the newline.
In Python 3, it’s print(item, end=" ")
.
If you want every number to display in the same place, use for example (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, it’s a bit more complicated; here you need to flush sys.stdout
or it won’t print anything until after the loop has finished:
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()
Change print item
to:
print item,
in Python 2.7
print(item, end=" ")
in Python 3
If you want to print the data dynamically use following syntax:
print(item, sep=' ', end='', flush=True)
in Python 3
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.
You can add a trailing comma to your print statement to print a space instead of a newline in each iteration:
print item,
Alternatively, if you’re using Python 2.6 or later, you can use the new print function, which would allow you to specify that not even a space should come at the end of each item being printed (or allow you to specify whatever end you want):
from __future__ import print_function
...
print(item, end="")
Finally, you can write directly to standard output by importing it from the sys module, which returns a file-like object:
from sys import stdout
...
stdout.write( str(item) )
A comma at the end of the print statement omits the new line.
for i in xrange(1,100):
print i,
but this does not overwrite.
To make the numbers overwrite each other, you can do something like this:
for i in range(1,100):
print "r",i,
That should work as long as the number is printed in the first column.
EDIT:
Here’s a version that will work even if it isn’t printed in the first column.
prev_digits = -1
for i in range(0,1000):
print("%s%d" % ("b"*(prev_digits + 1), i)),
prev_digits = len(str(i))
I should note that this code was tested and works just fine in Python 2.5 on Windows, in the WIndows console. According to some others, flushing of stdout may be required to see the results. YMMV.
By the way…… How to refresh it every time so it print mi in one place just change the number.
In general, the way to do that is with terminal control codes. This is a particularly simple case, for which you only need one special character: U+000D CARRIAGE RETURN, which is written 'r'
in Python (and many other languages). Here’s a complete example based on your code:
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
Some things about this that may be surprising:
- The
r
goes at the beginning of the string so that, while the program is running, the cursor will always be after the number. This isn’t just cosmetic: some terminal emulators get very confused if you do it the other way around.
- If you don’t include the last line, then after the program terminates, your shell will print its prompt on top of the number.
- The
stdout.flush
is necessary on some systems, or you won’t get any output. Other systems may not require it, but it doesn’t do any harm.
If you find that this doesn’t work, the first thing you should suspect is that your terminal emulator is buggy. The vttest program can help you test it.
You could replace the stdout.write
with a print
statement but I prefer not to mix print
with direct use of file objects.
“By the way…… How to refresh it every time so it print mi in one place just change the number.”
It’s really tricky topic. What zack suggested ( outputting console control codes ) is one way to achieve that.
You can use (n)curses, but that works mainly on *nixes.
On Windows (and here goes interesting part) which is rarely mentioned (I can’t understand why) you can use Python bindings to WinAPI (http://sourceforge.net/projects/pywin32/ also with ActivePython by default) – it’s not that hard and works well. Here’s a small example:
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 )
Or, if you want to use print
(statement or function, no difference):
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
module enables you to do many more interesting things with windows console… I’m not a big fan of WinAPI, but recently I realized that at least half of my antipathy towards it was caused by writing WinAPI code in C – pythonic bindings are much easier to use.
All other answers are great and pythonic, of course, but… What if I wanted to print on previous line? Or write multiline text, than clear it and write the same lines again? My solution makes that possible.
If you just want to print the numbers, you can avoid the loop:
# 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}msn'.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}msn'.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
Like the other examples,
I use a similar approach but instead of spending time calculating out the last output length, etc,
I simply use ANSI code escapes to move back to the beginning of the line and then clear that entire line before printing my current status output.
import sys
class Printer():
"""Print things to stdout on one line dynamically"""
def __init__(self,data):
sys.stdout.write("rx1b[K"+data.__str__())
sys.stdout.flush()
To use in your iteration loop you would just call something like:
x = 1
for f in fileList:
ProcessFile(f)
output = "File number %d completed." % x
Printer(output)
x += 1
I think a simple join should work:
nl = []
for x in range(1,10):nl.append(str(x))
print ' '.join(nl)
The best way to accomplish this is to use the r
character
Just try the below code:
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
change
print item
to
print " 33[K", item, "r",
sys.stdout.flush()
- “
I would like to make several statements that give standard output without seeing newlines in between statements.
Specifically, suppose I have:
for item in range(1,100):
print item
The result is:
1
2
3
4
.
.
.
How get this to instead look like:
1 2 3 4 5 ...
Even better, is it possible to print the single number over the last number, so only one number is on the screen at a time?
Use print item,
to make the print statement omit the newline.
In Python 3, it’s print(item, end=" ")
.
If you want every number to display in the same place, use for example (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, it’s a bit more complicated; here you need to flush sys.stdout
or it won’t print anything until after the loop has finished:
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()
Change print item
to:
print item,
in Python 2.7print(item, end=" ")
in Python 3
If you want to print the data dynamically use following syntax:
print(item, sep=' ', end='', flush=True)
in Python 3
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.
You can add a trailing comma to your print statement to print a space instead of a newline in each iteration:
print item,
Alternatively, if you’re using Python 2.6 or later, you can use the new print function, which would allow you to specify that not even a space should come at the end of each item being printed (or allow you to specify whatever end you want):
from __future__ import print_function
...
print(item, end="")
Finally, you can write directly to standard output by importing it from the sys module, which returns a file-like object:
from sys import stdout
...
stdout.write( str(item) )
A comma at the end of the print statement omits the new line.
for i in xrange(1,100):
print i,
but this does not overwrite.
To make the numbers overwrite each other, you can do something like this:
for i in range(1,100):
print "r",i,
That should work as long as the number is printed in the first column.
EDIT:
Here’s a version that will work even if it isn’t printed in the first column.
prev_digits = -1
for i in range(0,1000):
print("%s%d" % ("b"*(prev_digits + 1), i)),
prev_digits = len(str(i))
I should note that this code was tested and works just fine in Python 2.5 on Windows, in the WIndows console. According to some others, flushing of stdout may be required to see the results. YMMV.
By the way…… How to refresh it every time so it print mi in one place just change the number.
In general, the way to do that is with terminal control codes. This is a particularly simple case, for which you only need one special character: U+000D CARRIAGE RETURN, which is written 'r'
in Python (and many other languages). Here’s a complete example based on your code:
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
Some things about this that may be surprising:
- The
r
goes at the beginning of the string so that, while the program is running, the cursor will always be after the number. This isn’t just cosmetic: some terminal emulators get very confused if you do it the other way around. - If you don’t include the last line, then after the program terminates, your shell will print its prompt on top of the number.
- The
stdout.flush
is necessary on some systems, or you won’t get any output. Other systems may not require it, but it doesn’t do any harm.
If you find that this doesn’t work, the first thing you should suspect is that your terminal emulator is buggy. The vttest program can help you test it.
You could replace the stdout.write
with a print
statement but I prefer not to mix print
with direct use of file objects.
“By the way…… How to refresh it every time so it print mi in one place just change the number.”
It’s really tricky topic. What zack suggested ( outputting console control codes ) is one way to achieve that.
You can use (n)curses, but that works mainly on *nixes.
On Windows (and here goes interesting part) which is rarely mentioned (I can’t understand why) you can use Python bindings to WinAPI (http://sourceforge.net/projects/pywin32/ also with ActivePython by default) – it’s not that hard and works well. Here’s a small example:
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 )
Or, if you want to use print
(statement or function, no difference):
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
module enables you to do many more interesting things with windows console… I’m not a big fan of WinAPI, but recently I realized that at least half of my antipathy towards it was caused by writing WinAPI code in C – pythonic bindings are much easier to use.
All other answers are great and pythonic, of course, but… What if I wanted to print on previous line? Or write multiline text, than clear it and write the same lines again? My solution makes that possible.
If you just want to print the numbers, you can avoid the loop:
# 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}msn'.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}msn'.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
Like the other examples,
I use a similar approach but instead of spending time calculating out the last output length, etc,
I simply use ANSI code escapes to move back to the beginning of the line and then clear that entire line before printing my current status output.
import sys
class Printer():
"""Print things to stdout on one line dynamically"""
def __init__(self,data):
sys.stdout.write("rx1b[K"+data.__str__())
sys.stdout.flush()
To use in your iteration loop you would just call something like:
x = 1
for f in fileList:
ProcessFile(f)
output = "File number %d completed." % x
Printer(output)
x += 1
I think a simple join should work:
nl = []
for x in range(1,10):nl.append(str(x))
print ' '.join(nl)
The best way to accomplish this is to use the r
character
Just try the below code:
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
change
print item
to
print " 33[K", item, "r",
sys.stdout.flush()
- “