Loops
for, while, range, break, continue, and the for-else surprise
Iteration is the engine of automation. Every batch job, every data pipeline, every web scraper, every game loop, every file processor — they all loop. Python has two looping constructs: for iterates over any iterable; while repeats while a condition holds true. Mastering loops means writing efficient, readable code that processes data at scale.
Every snippet on this page runs in your browser — no setup required.
Real-world impact
Loops are everywhere in real code. A web server loops over incoming requests. A machine learning library loops over training batches. A file processor loops over lines. A game engine loops 60 times per second. Understanding loops deeply — including when to break, when to continue, and how to avoid common pitfalls — is essential.
The for loop
The simplest form: iterate over a sequence.
for works on any iterable: lists, tuples, strings, sets, dicts, files, generators, and your own custom classes (covered later under Iterators and Generators).
Iterating a dict yields keys by default. Use .items() for key-value pairs, .values() for just values. This is a common source of confusion for newcomers.
range
range(stop), range(start, stop), and range(start, stop, step) produce arithmetic progressions lazily. They are the canonical way to loop "N times".
The stop parameter is exclusive. range(5) yields 0, 1, 2, 3, 4 — not 5. This is Python's universal convention for ranges and slices, and it prevents off-by-one errors most of the time. But you still need to watch for them when converting between 0-indexed and 1-indexed logic.
enumerate
If your loop needs the index, do not write range(len(xs)). Use enumerate.
enumerate is clearer, more Pythonic, and less error-prone than manual indexing.
zip
zip iterates multiple sequences in parallel, stopping at the shortest one.
If the sequences have different lengths, zip stops at the shortest.
reversed
Iterate a sequence backwards without mutating it.
The while loop
while repeats as long as a condition is true.
Use while True plus break for "loop until something happens" code where the loop body knows when to stop.
Infinite loops
while True: without a break is an infinite loop. This is useful for servers ("run forever") and event loops ("keep processing"), but deadly in scripts. Always ensure your while loop has a way to exit.
break and continue
breakexits the innermost loop immediately.continueskips the rest of the current iteration and goes back to the top.
for ... else (the weird one)
Both for and while accept an else: block, which runs only if the loop completed normally (no break). It is most useful for search loops.
The else block runs only if we never hit break, which is exactly what we want for "searched but found nothing" logic.
for...else is rare and confusing
The for...else pattern is Pythonic, but it confuses many readers because "else" suggests "if the loop didn't run," when it actually means "if the loop ran to completion without breaking." Use it sparingly and add a comment explaining why, or rewrite with a flag variable if clarity demands it.
while ... else
The same else logic applies to while loops.
Avoiding common pitfalls
Modifying a list while iterating over it
Changing a list's length during iteration invalidates the iterator and leads to skipped items or infinite loops. If you must remove items, iterate over a copy: for x in xs[:] or build a new list with a comprehension.
Better: use a list comprehension to build a new list.
Challenges
Define a function digit_sum(n) that takes a non-negative integer n and returns the sum of its decimal digits. Use a while loop. For example, digit_sum(1234) returns 10.
Define a function first_prime_over(n) that returns the smallest prime number strictly greater than n. Use the for ... else pattern from above for the inner primality test.
Define a function count_vowels(text) that returns the number of vowels (a, e, i, o, u, case-insensitive) in text. Use a for loop.
What does this code print?
for i in range(3):
if i == 1:
continue
print(i)
0\n1\n2
0\n2
0\n1
2
When does a for ... else clause execute?
Always, after the loop body finishes
When the loop body raises an exception
Only when the loop finishes without hitting break
Only when the iterable is empty
What is the output of this code?
for i in range(5):
if i == 3:
break
print(i)
0
4
3
A NameError
What does enumerate(["a", "b", "c"], start=1) yield?
(0, "a"), (1, "b"), (2, "c")
(1, "a"), (2, "b"), (3, "c")
("a", 1), ("b", 2), ("c", 3)
["a", "b", "c"]
Loops naturally lead into a tighter syntactic form: comprehensions.