189

I was wondering if it was possible to remove items you have printed in Python - not from the Python GUI, but from the command prompt. e.g.

a = 0  
for x in range (0,3):  
    a = a + 1  
    b = ("Loading" + "." * a)
print (a)

so it prints

>>>Loading   
>>>Loading. 
>>>Loading.. 
>>>Loading...

But, my problem is I want this all on one line, and for it it remove it self when something else comes along. So instead of printing "Loading", "Loading.", "Loading... I want it to print "Loading.", then it removes what is on the line and replaces it with "Loading.." and then removes "Loading.." and replaces it (on the same line) with "Loading...". It's kind of hard to describe.

p.s I have tried to use the Backspace character but it doesn't seem to work ("\b")

Tomerikoo
  • 18,379
  • 16
  • 47
  • 61
Alex
  • 2,189
  • 3
  • 15
  • 9
  • 7
    Whats the point of the `a` variable here? You can just use x as your variable and it will do the same thing! – John Howard Mar 13 '11 at 17:31
  • 2
    Two questions: 1. shouldn't be the `print()` command indentet to the level of the inner of the for-loop? Currently, your code doesn't print some kind of progress, but only the final state. 2. shouldn't it be `print (b)`? Currently only integers are printed, not the `"Loading"` as mentioned in the question. – Qaswed Aug 19 '19 at 13:14

3 Answers3

275

Just use CR to go to beginning of the line.

import time
for x in range (0,5):  
    b = "Loading" + "." * x
    print (b, end="\r")
    time.sleep(1)
gg349
  • 21,996
  • 5
  • 54
  • 64
Keith
  • 42,110
  • 11
  • 57
  • 76
  • 1
    It works in windows 7 basic terminal. In python 2.7, I simply use `print "whatever to be removed\r",` Thanks! – PhilMacKay Oct 31 '16 at 15:42
  • 7
    Any idea for terminal _( IDLE )_? – Nouman Jul 29 '17 at 10:02
  • 39
    `sys.stdout.write("\033[K")` to clear the previous print –  Mar 09 '18 at 13:39
  • 3
    @h0ussni I don't know sorcery that is but it works great – Dustin Michels Mar 15 '19 at 20:05
  • 13
    `sys.stdout.write('\033[2K\033[1G')` erase and go to beginning of line – sound wave Jun 19 '19 at 22:01
  • 16
    Side note: to make this work in jupyter (in python3), use: `print("\r", b, end="")` – DSH Mar 29 '20 at 22:12
  • To clear all or n previously printed lines and move the cursor back to the start without flushing the entire console output every time (`os.system('cls' if os.name=='nt' else 'clear')` cross OS compatible) use `cursor_up = '\x1b[1A';erase_line = '\x1b[2K';print("hi\nyou\nthere\nletstry!");print((cursor_up + erase_line)*4 +cursor_up);print("hi\nyou\nthere\nletstry!")` – do-me Jan 16 '21 at 19:29
  • 2
    Instead of `"." * x`, you should try `"." * (x % 3 + 1)` to avoid stuff like `Loading......` – deb Feb 19 '21 at 15:15
  • in VS Code, and in Notebooks (ipynb), use these together: `print("\r" , end="")` `print("delta = ", delta, end="")` – Khalil Youssefi Jun 25 '21 at 11:52
143

One way is to use ANSI escape sequences:

import sys
import time
for i in range(10):
    print("Loading" + "." * i)
    sys.stdout.write("\033[F") # Cursor up one line
    time.sleep(1)

Also sometimes useful (for example if you print something shorter than before):

sys.stdout.write("\033[K") # Clear to the end of line
marceloow
  • 117
  • 9
Sven Marnach
  • 574,206
  • 118
  • 941
  • 841
  • 12
    Doesn't work in python notebooks :( – markroxor May 12 '18 at 14:07
  • 7
    Is it necessary to use sys.stdout.write() ? Can you just do print("\033[K",end='') ? – Trevor Jul 11 '18 at 21:11
  • 4
    @Trevor This answer was written to work in both Python 2 and 3. I know the question is tagged "python-3.x", but back in 2011 hardly anyone was using Python 3, so I wrote an answer that works in both versions. If you are using Python 3, you can use `print(..., end="")` if you prefer. – Sven Marnach Jul 12 '18 at 10:01
  • 5
    Could you theoretically do `sys.stdout.write("\033[F" * 2)` if you wanted to cursor up 2 lines? – madladzen Jul 23 '20 at 13:37
  • 4
    @madladzen This should work. The ANSI sequence also supports a parameter, so you could also use `sys.stdout.write("\033[2F")`. – Sven Marnach Jul 23 '20 at 14:13
  • I know I'm late, but my two cents: `"\033[F" * 2`, or `"\033[2F"` don't always work, as python adds the new line AFTER you go higher. So if you try to go 2 lines above and you only have one line printed, you will print the new thing on the next line, but if you have more than 1 line, the last one will be rewritten – Mahrkeenerh Jan 31 '22 at 12:44
  • @Mahrkeenerh I can't quite follow. `sys.stdout.write()` does not add any newline characters. `print()` does, which is why the code isn't using it. This answer was originally written with Python 2 in mind. In Python 3, you can also use `print(..., end="")`, as already mentioned in the comments above. – Sven Marnach Feb 01 '22 at 09:05
  • My mistake. I was replying to a comment, and misread the `write` instead of `print`. What I was talking about was a `print("\033[F" * 2)` with no `end=''` – Mahrkeenerh Feb 01 '22 at 09:09
41
import sys
import time

a = 0  
for x in range (0,3):  
    a = a + 1  
    b = ("Loading" + "." * a)
    # \r prints a carriage return first, so `b` is printed on top of the previous line.
    sys.stdout.write('\r'+b)
    time.sleep(0.5)
print (a)

Note that you might have to run sys.stdout.flush() right after sys.stdout.write('\r'+b) depending on which console you are doing the printing to have the results printed when requested without any buffering.

Ma0
  • 15,057
  • 4
  • 35
  • 65
unutbu
  • 842,883
  • 184
  • 1,785
  • 1,677