There are a lot of simple ideas that float about in programming. Many that are conceptually simple, yet end up being a bit tricky for you to implement. Right until the moment you see how somebody else does it, and you have a more concrete feeling for the simplicity.

What follows is an advanced common sense idea that should help you with printing inside loops.

In some batch script you might have:

for word in words:

This works alright, except you don't have visibility into progress or details about what's going on.

for word in words:
    print(f"Processing {word}...")

This lets you follow along in your terminal, but also is kind of miserable if your process is dealing with a lot of data. Suddenly you have thousands of lines of output filling your terminal.

Often what you want is just the most recent word being processed. The trick here is that you can use some ANSI escape codes to nicely format your terminal output.

ESC [ is called a Control Sequence Introducer (CSI). If you print that to your standard output, along with some parameters, you can control your cursor position, clear a line, or the whole screen.

So what we can do to update the value "inplace" is to clear the screen, position the cursor back at the top left of the screen, and then re-print the values.

CSI = "\x1b["
CLEAR = CSI + "2J"
for word in words:
    print(CLEAR + TOP_LEFT)
    print(f"processing {word}...")

Now at every iteration you can just clear out your screen and actually just show one item at a time.

This can work well enough, for a couple of lines (or, if you're that kind of person, just memorizing \x1b[2J\x1b[;H as a preface to your printing and inlining that).

But you might end up not being able to read things if your program is a bit too fast, and suddenly your program is trying to clear your terminal a hundred times a second and you have no time to read any of the output.

(An asciinema recording of extremely fast output would actually cause this article's Javascript to hang, so you'll have to use your imagination on this one).

But for this, you can quickly whip up some rate limiting in a couple lines of code.

import time
last_print_time = time.time()
for word in words:
    now = time.time()
    # print once a second (adjust to taste)
    if (now - last_print_time) > 1:
        print(CLEAR + TOP_LEFT)
        print(f"Processing {word}...")
        last_print_time = now

I am sure you could code golf this down even further, but even this is just a couple of lines.

With this we end up with something relatively legible and nice on the eyes.

This is a bit of a simple example, but in practice this can be useful for printing out a lot of information on the current task. All without filling up your terminal with noise.