Say you want to print the numbers 1 to 5. You could write print five times and be done. Now make it 1 to 500. Nobody types print five hundred times. This is the exact job a loop was built for, and it fits on two lines:
for n in range(1, 6):
print(n)1 2 3 4 5
Read it in plain words. For each number n in the range 1 up to 6, print n. The loop ran the indented line five times, once for 1, once for 2, and so on, then stopped on its own. Change 6 to 501 and the same two lines count to 500. That is the whole appeal of a loop. You describe the work once and Python repeats it.
You need Python 3 and about half an hour. This part sits right on top of Part 5, where you learned if, elif and else, because loops and conditions work together all the time. Nothing new to install. Copy each block, run it, and your screen should match the output shown. If you are a career switcher, this is the part where a program can do an hour of manual clicking in under a second.
for: once for each item
A for loop walks through a sequence and runs its block once for each thing it finds. The shape is the word for, a name for the current item, the word in, a sequence, a colon, then an indented block. The indentation rule is the same one from Part 5, four spaces, and the colon is just as required.
range gives you numbers to count
range() produces a run of whole numbers. The catch that surprises everyone once is that the end number is left out. range(1, 6) gives you 1, 2, 3, 4, 5, and stops before 6. Here is the shape in a small table you can lean on.
| You write | You get | Note |
|---|---|---|
| range(5) | 0 1 2 3 4 | starts at 0, stops before 5 |
| range(1, 6) | 1 2 3 4 5 | start included, end left out |
| range(0, 10, 2) | 0 2 4 6 8 | third number is the step |
| range(3, 0, -1) | 3 2 1 | a negative step counts down |
The end being left out is not a bug to fight, it is what makes range(len(x)) line up with the valid positions of a sequence later on. For now, just remember that range(1, 6) stops at 5.
range(1, 4) gives 1, 2 and 3, so the body runs three times and then the loop ends.
Looping over text, not just numbers
A for loop is not only for counting. It walks through any sequence, and a string is a sequence of characters. This prints each letter of a word on its own line.
for letter in 'cat':
print(letter)c a t
You do not manage a counter here at all. Python hands you each item in turn. That is why looping over the items directly reads so much better than looping over their positions.
while: keep going while it is true
A for loop is perfect when you know the sequence in advance. Sometimes you do not. You want to keep going until something happens, and you cannot say up front how many turns that will take. That is a while loop. It checks a condition, runs the block if the condition is true, then goes back and checks again.
n = 3
while n > 0:
print(n)
n = n - 1
print('Liftoff')3 2 1 Liftoff
Look closely at the line n = n – 1. Each turn it makes n one smaller. Without it, n would stay at 3, the condition n > 0 would stay true, and the loop would never stop. That line is what lets the loop end, and forgetting it is the single most common while bug there is.
While the condition is true the body runs and loops back. When it turns false, the loop exits.
The loop that never ends, and how to stop it
Every Python programmer writes an accidental forever loop at some point. Usually it is a while whose counter never changes. Here is one on purpose so you know the feeling:
n = 3
while n > 0:
print(n)3 3 3 3 ... forever
Nothing changes n, so the condition is true on every pass and the numbers pour out. To stop a runaway program, press Ctrl and C together in the terminal. That works on Windows, macOS and Linux. Python halts the loop and shows a KeyboardInterrupt, which here is not an error you caused by bad code, it is just how you tell a running program to quit. The fix is to change n inside the loop so the condition can eventually become false.
break and continue: leaving early, skipping ahead
Two small words give you finer control inside any loop. break stops the loop right now and moves on to whatever comes after it. continue skips the rest of this turn and jumps straight to the next one.
for n in range(1, 100):
if n * n > 50:
print('First square over 50:', n)
breakFirst square over 50: 8
The loop was ready to run up to 99 times. It stopped at 8, the first number whose square passes 50, because break ended it. Now continue, which skips rather than stops. This prints only the odd numbers by jumping over the even ones.
for n in range(1, 7):
if n % 2 == 0:
continue
print(n)1 3 5
The % sign here is the remainder operator from Part 3. When n % 2 is 0 the number is even, so continue skips the print and the loop moves to the next number. Odd numbers fall through and get printed.
break jumps out of the loop for good. continue jumps back to the top for the next turn.
for or while: which one?
Most of the time the choice is easy. If you know the collection or the count in advance, use for. If you are waiting on a condition and cannot say how many turns it takes, use while. This table lines them up.
| Question | for loop | while loop |
|---|---|---|
| Best when | you know the items or count | you wait on a condition |
| Ends because | the sequence runs out | the condition turns false |
| Counter | Python handles it | you update it yourself |
| Forever risk | very low | high if you forget to update |
| Typical use | each row, each name, count to N | menus, retries, keep asking |
A worked example: a times table
Here is a small program built the way you would build it for real, one honest mistake included. The goal is a times table for 7, from 7 times 1 up to 7 times 10. First try counts with a plain range.
num = 7
for i in range(1, 10):
print(num, 'x', i, '=', num * i)7 x 1 = 7 7 x 2 = 14 7 x 3 = 21 7 x 4 = 28 7 x 5 = 35 7 x 6 = 42 7 x 7 = 49 7 x 8 = 56 7 x 9 = 63
Count the rows. Nine, not ten. The table stops at 7 times 9 because range(1, 10) leaves out the 10, exactly the trap from the table earlier. This is an off by one, the most common counting bug in any language. The fix is to end the range one higher.
num = 7
for i in range(1, 11):
print(num, 'x', i, '=', num * i)7 x 1 = 7 ... 7 x 10 = 70
Now the last line reads 7 times 10 is 70. Whenever a loop does one turn too few or one too many, look at the range ends first. That instinct will save you real time.
print('My Expense Tracker')
total = 0.0
while True:
category = input('Category or done: ')
if category == 'done':
break
amount = float(input('Amount: '))
total = total + amount
print('Saved', amount, 'for', category)
print('Total spent:', total)My Expense Tracker Category or done: Groceries Amount: 250 Saved 250.0 for Groceries Category or done: Bus Amount: 40 Saved 40.0 for Bus Category or done: done Total spent: 290.0
2 4 6 8 10
Show solution
for n in range(2, 11, 2):
print(n)2 4 6 8 10
The step of 2 walks two at a time, and the end of 11 keeps 10 in, since the range stops before 11.
Loop questions beginners actually ask
When do I use for and when do I use while? Use for when you know what to loop over, a list, a string, or a count with range. Use while when you are waiting on a condition and do not know the number of turns, like reading input until the user is done.
Why does range(1, 5) stop at 4? The end number is left out by design. range(1, 5) gives 1, 2, 3, 4. If you want 5 in it, write range(1, 6). Almost every off by one loop bug traces back to this.
My program is stuck printing forever. What do I do? Press Ctrl and C in the terminal to stop it, on any operating system. Then look at your while loop and make sure something inside it changes the value the condition tests.
What is the difference between break and continue? break leaves the loop completely. continue skips the rest of the current turn and goes back to the top for the next one. Neither one touches the loop after it finishes.
Can I loop over a word or only numbers? You can loop over any sequence. A string gives you one character per turn, and lists, which are next in Part 7, give you one item per turn. range is only for when you specifically want numbers.
You can now write a for loop over a range or a string, count with range including a step, write a while loop that ends when its condition turns false, leave a loop early with break, skip a turn with continue, and rescue a runaway loop with Ctrl and C.
Part 7 gives your loops something better to walk over than a range of numbers. You will meet the list, Python’s everyday container, along with tuples and sets, and the expense tracker will finally keep every entry instead of only a running total. Keep expenses.py exactly as it stands, because Part 7 grows it again. Try the even numbers task first, and open the solution only to check yourself.
References
Python docs: for statements
Python docs: the range function
Python docs: the while statement


DrJha