Print to the same line and not a new line?

Viewed 151769

Basically I want to do the opposite of what this guy did... hehe.

Python Script: Print new line each time to shell rather than update existing line

I have a program that is telling me how far along it is.

for i in some_list:
    #do a bunch of stuff.
    print i/len(some_list)*100," percent complete"

So if len(some_list) was 50, I'd get that last line printed 50 times over. I want to print one line and keep updating that line. I know I know this is probably the lamest question you'll read all day. I just can't figure out the four words I need to put into google to get the answer.

Update! I tried mvds' suggestion which SEEMED right. The new code

print percent_complete,"           \r",

Percent complete is just a string (I was abstracting the first time now I an trying to be literal). The result now is that it runs the program, doesn't print ANYTHING until after the program is over, and then prints "100 percent complete" on one and only one line.

Without the carriage return (but with the comma, half of mvds' suggestion) it prints nothing until the end. And then prints:

0 percent complete     2 percent complete     3 percent complete     4 percent complete    

And so on. So now the new issue is that with the comma it doesn't print until the program is finished.

With the carriage return and no comma it behaves the exact same as with neither.

19 Answers

In Python 3.3+ you don’t need sys.stdout.flush(). print(string, end='', flush=True) works.

So

print('foo', end='')
print('\rbar', end='', flush=True)

will overwrite ‘foo’ with ‘bar’.

Late to the game - but since the none of the answers worked for me (I didn't try them all) and I've come upon this answer more than once in my search ... In python 3, this solution is pretty elegant and I believe does exactly what the author is looking for, it updates a single statement on the same line. Note, you may have to do something special if the line shrinks instead of grows (like perhaps make the string a fixed length with padded spaces at the end)

if __name__ == '__main__':
    for i in range(100):
        print("", end=f"\rPercentComplete: {i} %")
        time.sleep(0.2)

If you are using Spyder, the lines just print continuously with all the previous solutions. A way to avoid that is using:

for i in range(1000):
    print('\r' + str(round(i/len(df)*100,1)) + '% complete', end='')
    sys.stdout.flush()

As of end of 2020 and Python 3.8.5 on linux console for me only this works:

print('some string', end='\r')

Credit goes to: This post

For Python 3+

for i in range(5):
    print(str(i) + '\r', sep='', end ='', file = sys.stdout , flush = False)

As of 2021, for Python 3.9.0 the following solution worked for me in Windows 10, Pycharm.

print('\r some string ', end='', flush=True)

For Python 3.6+ and for any list rather than just ints, as well as using the entire width of your console window and not crossing over to a new line, you could use the following:

note: please be informed, that the function get_console_with() will work only on Linux based systems, and as such you have to rewrite it to work on Windows.

import os
import time

def get_console_width():
    """Returns the width of console.

    NOTE: The below implementation works only on Linux-based operating systems.
    If you wish to use it on another OS, please make sure to modify it appropriately.
    """
    return int(os.popen('stty size', 'r').read().split()[1])


def range_with_progress(list_of_elements):
    """Iterate through list with a progress bar shown in console."""

    # Get the total number of elements of the given list.
    total = len(list_of_elements)
    # Get the width of currently used console. Subtract 2 from the value for the
    # edge characters "[" and "]"
    max_width = get_console_width() - 2
    # Start iterating over the list.
    for index, element in enumerate(list_of_elements):
        # Compute how many characters should be printed as "done". It is simply
        # a percentage of work done multiplied by the width of the console. That
        # is: if we're on element 50 out of 100, that means we're 50% done, or
        # 0.5, and we should mark half of the entire console as "done".
        done = int(index / total * max_width)
        # Whatever is left, should be printed as "unfinished"
        remaining = max_width - done
        # Print to the console.
        print(f'[{done * "#"}{remaining * "."}]', end='\r')
        # yield the element to work with it
        yield element
    # Finally, print the full line. If you wish, you can also print whitespace
    # so that the progress bar disappears once you are done. In that case do not
    # forget to add the "end" parameter to print function.
    print(f'[{max_width * "#"}]')


if __name__ == '__main__':
    list_of_elements = ['a', 'b', 'c', 'd', 'e', 'f', 'g', 'h', 'i', 'j']
    for e in range_with_progress(list_of_elements):
        time.sleep(0.2)

If you are using Python 3 then this is for you and it really works.

print(value , sep='',end ='', file = sys.stdout , flush = False)

Just figured this out on my own for showing a countdown but it would also work for a percentage.

import time
#Number of seconds to wait
i=15
#Until seconds has reached zero
while i > -1:
    #Ensure string overwrites the previous line by adding spaces at end
    print("\r{} seconds left.   ".format(i),end='')
        time.sleep(1)
        i-=1
    print("") #Adds newline after it's done

As long as whatever comes after '/r' is the same length or longer (including spaces) than the previous string, it will overwrite it on the same line. Just make sure you include the end='' otherwise it will print to a newline. Hope that helps!

for object "pega" that provides StartRunning(), StopRunning(), boolean getIsRunning() and integer getProgress100() returning value in range of 0 to 100, this provides text progress bar while running...

now = time.time()
timeout = now + 30.0
last_progress = -1

pega.StartRunning()

while now < timeout and pega.getIsRunning():
    time.sleep(0.5)
    now = time.time()

    progress = pega.getTubProgress100()
    if progress != last_progress:
        print('\r'+'='*progress+'-'*(100-progress)+' ' + str(progress) + "% ", end='', flush=True)
        last_progress = progress

pega.StopRunning()

progress = pega.getTubProgress100()
print('\r'+'='*progress+'-'*(100-progress)+' ' + str(progress) + "% ", flush=True)

In those cases, with python 3.x, I'm using the following code:

for ii in range(100):
    print(f"\rPercent: {ii+1} %", end=" "*20)

The problem with some other answers is that if your printed string goes shorter at one step, the last characters from the previous string won't be overwrited.

So I use end=" "*20 in order to overwrite the previous line with whitespace. Just make sure that 20 is longer than the length of your longest string.

Related