Computers exist to repeat things. A person who had to add up a million numbers would quit; a loop does it before you finish blinking. This lesson teaches Python's two loops and the control statements that steer them, and it does so carefully, because loops are where beginning programmers first feel the gap between reading code and writing it. By the end you will have written multiplication tables, summed series, searched for values, validated input, and solved FizzBuzz, the most famous interview warm-up in the world.
The two loops divide the work cleanly. Use for when you know what collection of things you are walking through: every number in a range, every character in a string, every line in a file. Use while when you only know the stopping condition: keep asking until the answer is valid, keep playing until the player quits. Learning which loop a problem wants is half of this lesson; the syntax is the easy half.
What you will learn in Part 3
- while loops for repeat-until-condition problems
- for loops with range, strings, and collections
- break to leave a loop early and continue to skip one round
- The else clause on loops, and when it is actually useful
- Nested loops, and the multiplication table pattern
- The accumulator, counter, and search patterns used in all real code
Note
Before you start
You need variables and f-strings from Part 1 and conditions from Part 2, because every interesting loop has an if inside it. The playground below runs all the examples live.
1. The while loop: repeat until told otherwise
A while loop is an if that keeps happening. Python checks the condition; if it is truthy, the block runs, and then the condition is checked again, around and around until the check fails. That structure puts a sacred duty on you: something inside the block must eventually change the condition, or the loop never ends. Every programmer alive has written an accidental infinite loop; in a terminal, Ctrl+C interrupts it, and in our playground the runner simply cuts it off.
countdown = 5
while countdown > 0:
print(countdown)
countdown -= 1 # the line that makes the loop finite
print("Liftoff!")
# 5 4 3 2 1 Liftoff!
Trace it once by hand, the way you traced the grade ladder in Part 2. countdown starts at 5, the condition 5 > 0 holds, we print and decrement. The loop body runs five times in total, and when countdown reaches 0 the condition finally fails and execution falls through to the liftoff line. That habit of finger-tracing a loop for the first two and last two iterations will save you from almost every off-by-one bug this year.
The honest use case for while is when the number of repetitions is unknowable in advance. The classic example is input validation: ask, check, and ask again until the answer is acceptable. You will write this exact shape in real programs constantly, and it cannot be written naturally with for, because nobody knows how many tries the user will need.
# Keep asking until we get a valid choice (terminal version)
choice = ""
while choice not in ("rock", "paper", "scissors"):
choice = input("rock, paper or scissors? ").lower().strip()
print(f"You chose {choice}")
2. The for loop and range
A for loop walks through the items of a sequence, one per iteration, and hands each item to a name you choose. The most common sequence in early code is range, which generates evenly spaced integers on demand. range(5) yields 0 through 4, range(1, 6) yields 1 through 5, and range(0, 50, 10) counts by tens. Note the asymmetry that trips everyone exactly once: the start is included, the stop is excluded. That convention is deliberate, because it makes range(len(items)) line up perfectly with valid indexes, and lengths add up cleanly when you split ranges.
for i in range(5):
print(i, end=" ") # 0 1 2 3 4
print()
for year in range(2024, 2027):
print(f"Report for {year}")
total = 0
for n in range(1, 101):
total += n
print(f"1 + 2 + ... + 100 = {total}") # 5050
That last example is the accumulator pattern, and it might be the single most reused shape in all of programming: create a variable before the loop, fold one item into it each iteration, and use the result after. Sums, products, counts, joined strings, and (from Part 5 onward) built-up lists are all accumulators. When a problem says "total", "count", or "combine", your fingers should start typing an accumulator before your brain finishes reading.
for is not limited to range. Any sequence works, and strings are sequences of characters, which makes text processing feel effortless. Counting vowels, one of the practice examples in the Learn Python app, is four lines: an accumulator, a loop over the string, a membership test, and a print.
sentence = "Learn Python by doing"
vowels = 0
for ch in sentence.lower():
if ch in "aeiou":
vowels += 1
print(f"{vowels} vowels in: {sentence}") # 7 vowels
Checkpoint
How many times does the body of "for i in range(2, 10, 3)" run?
3. break, continue, and the loop else
Two statements steer a running loop. break leaves the loop immediately, jumping to the first line after it; continue abandons the current iteration and goes straight to the next check. break turns while True, an intentionally infinite loop, into the cleanest way to express ask-then-decide flows. continue shines as an early filter that keeps the interesting code unindented: when an item is irrelevant, skip it at the top of the body and let the real work breathe.
# break: search for the first number divisible by 7 and 5
for n in range(1, 200):
if n % 7 == 0 and n % 5 == 0:
print(f"Found it: {n}") # 35
break
# continue: process only the valid readings
readings = [21.5, -999, 22.1, -999, 23.8]
for r in readings:
if r == -999: # sensor error code
continue
print(f"Temperature: {r}")
Python adds one construct most languages lack: an else clause on loops. The else block runs only when the loop finished without hitting break. It reads oddly the first time, but it solves the search problem perfectly: if the loop broke, we found the thing; if the else ran, we exhausted the options. Without it you would manage a found flag by hand, which is exactly what the else replaces.
target = 17
for n in (4, 9, 12, 21):
if n == target:
print("Found the target")
break
else:
print(f"{target} is not in the data") # this runs
4. Nested loops and the multiplication table
Loops nest: put one inside another and the inner loop runs completely for every single pass of the outer one. The canonical example, and one of the most popular lessons in the Learn Python app, is the multiplication table. The outer loop picks the row, the inner loop walks the columns, and an f-string keeps the numbers aligned. Nested loops multiply work quickly, ten by ten is a hundred iterations, so they are also your first taste of thinking about how much work a program does, a thread we pick up properly in the generators lesson, Part 9.
for row in range(1, 6):
for col in range(1, 6):
print(f"{row * col:4}", end="")
print() # end the row
# 1 2 3 4 5
# 2 4 6 8 10
# 3 6 9 12 15
# 4 8 12 16 20
# 5 10 15 20 25
Checkpoint
In a nested loop where the outer runs 4 times and the inner runs 3 times per pass, how often does the innermost statement execute?
5. Putting it together: FizzBuzz and friends
FizzBuzz is the classic test of whether someone can combine a loop with conditions: print the numbers 1 to N, but print Fizz for multiples of 3, Buzz for multiples of 5, and FizzBuzz for multiples of both. The trap is order, straight from Part 2: you must test the most specific condition, divisible by both, first. The playground below has a working version plus three exercises that turn this lesson into reflexes. Run it, break it, fix it.
Exercise 1 hides a real lesson: the combined case for 4 and 6 is their least common multiple, 12, not their product 24, and the modulo test must use it. Tiny puzzles like that are why loop practice matters; the syntax is learned in an hour, but the habit of predicting what code will do before running it takes deliberate reps. Five more loop exercises, with instant feedback, are in the Flow Control quiz of the app at the end of this page.
6. Choosing between for and while
| You are thinking... | Loop | Typical shape |
|---|---|---|
| Do this for every item in a known collection | for | for item in items: |
| Do this exactly N times | for | for i in range(n): |
| Keep going until something happens | while | while not done: |
| Ask or retry until valid | while | while True: ... break |
| Walk two collections in step | for | for a, b in zip(xs, ys): (Part 5) |
When in doubt, reach for for. It is harder to write an infinite loop with for, the loop variable is managed for you, and most real-world repetition is over a collection anyway. Reserve while for genuinely open-ended repetition, and when you do use it, write the line that changes the condition first, before the body, so you can never forget it.
There is also a translation skill hiding under the syntax, and it is worth practicing deliberately: real problems do not arrive labeled with the loop they want. A requirement like "send a reminder to every student who has not paid" has to become "loop over students, test a condition, act on the matches" in your head before any code happens. Train the translation by narrating problems aloud in loop language: for each item, do what, unless what, until what. It feels silly for a week and then becomes how you read every task, and interviewers test exactly this translation far more often than they test syntax.
One readability rule will serve you for decades: when a loop body grows past a handful of lines, the body wants to become a function. A loop that reads for order in orders: process(order) tells the whole story in one line, while forty inline lines bury it. You will be able to do this properly after Part 4, and once you can, the combination of small loops calling named functions is what makes large programs feel small.
! Common mistakes to avoid
-
✕Forgetting to update the condition variable in a while loop, creating an infinite loop.
✓Write the update line (counter -= 1, done = ..., another input call) immediately when you write the while header, then fill in the body.
-
✕Expecting range(1, 10) to include 10.
✓The stop value is always excluded. To include 10, write range(1, 11). Check by printing list(range(...)) when unsure.
-
✕Using break in a nested loop and expecting it to exit both loops.
✓break only exits the innermost loop. To leave both, set a flag, or better, move the loops into a function and return, as Part 4 shows.
-
✕Modifying a collection while looping over it.
✓Removing items from a list you are iterating skips elements unpredictably. Loop over a copy, or build a new collection with the items you keep; Part 5 makes this pattern easy.
? Frequently asked questions
Which is faster, for or while? +
For walking a collection, for is both faster and clearer because Python manages the iteration internally. The difference matters far less than choosing the loop that expresses your intent; readable code gets optimized later, unreadable code gets rewritten.
What is the loop variable i, and do I have to call it that? +
It is an ordinary variable that for reassigns each iteration. i is convention for an anonymous counter; the moment the value means something, name it: for row, for student, for price. Readable names are free.
Can a for loop count backwards? +
Yes: range(10, 0, -1) yields 10 down to 1. The third argument is the step, and a negative step counts down. The stop is still excluded, exactly as when counting up.
Is there a do-while loop in Python? +
Not as syntax. The idiom is while True with a break at the point where the exit condition becomes known, usually after the first piece of work has been done once.
7. Recap and what comes next
You now hold the second half of programming's engine: while for open-ended repetition, for and range for collections, break and continue for steering, the loop else for searches, nested loops for grids, and the accumulator pattern that underlies nearly every computation. Combined with Part 2's decisions, you can already express any algorithm; everything that follows in this course is about expressing them better.
The next step is the biggest quality-of-life upgrade in the whole syllabus. In Part 4, Python functions explained, you stop writing scripts and start building reusable tools with names, inputs, and outputs. Before you go, run the FizzBuzz exercises above once more without looking at the solution, and try the Flow Control lesson in the Learn Python app below; spaced repetition on loops pays off for the rest of the track, which you can always survey on the series hub.
Pro tip
When a loop misbehaves, add print(f"iteration {i}: variable = {x}") as the first line of the body. Watching five iterations of real values beats twenty minutes of staring. Remove the print when done; in Part 13 you will graduate to real debugging and testing tools.
Practice on the go
Learn Python, the free Android app
Every topic in this series lives in the app too: bite-size lessons, runnable examples, quizzes, mini projects, and an offline Python playground that runs on your phone.
Comments
0No comments yet. Be the first to share your thoughts.