Reference · module 7
Loops in depth
Everything this module explains, on one page.
range
Loop a fixed number of times.
- range(5) counts 0, 1, 2, 3, 4. Five numbers, and the five itself is not one of them.
- range(2, 6) starts at two. A third argument is the step: range(0, 10, 2) gives the even numbers.
- range does not build a list. It produces numbers as the loop asks, so range(1000000) costs nothing to make.
The mistake you are about to make
range(1, 5) → 1, 2, 3, 4, 5
range(1, 5) → 1, 2, 3, 4
The second number looks like "up to here". It is not included: the end is where it stops. To reach five you need range(1, 6).
while
Loop until something changes.
- while runs as long as its condition stays true, and checks it again before every pass.
- Something inside has to move the condition toward false. If nothing does, the loop never ends.
- Use for when you know how many times, and while when you do not: reading until the input is valid, for instance.
The mistake you are about to make
while True: with no break inside
while True: with a break inside
While True is a handy way to say "keep going", and often it is the right one. The exit then has to live inside the body: without a break it never ends.
break and continue
Leave a loop or skip a pass.
- break stops the loop at once. Nothing after it in the body runs, and the loop is not entered again.
- continue skips the rest of this pass and goes to the next one. The loop itself carries on.
- Inside nested loops both act on the nearest one only, which is a common surprise.
The mistake you are about to make
break inside nested loops leaves both
break leaves only the nearest loop
Break reads as "leave the loop", so inside two of them it looks like an exit. It ends the nearest one only, and the outer loop carries on.
enumerate and zip
Loop with an index, or over two lists.
- enumerate(items) hands back the position and the item together, so no counter has to be kept by hand.
- It starts at zero. enumerate(items, 1) starts at one, which is what a numbered list wants.
- zip walks two lists side by side and stops at the shorter one, without complaining.
The mistake you are about to make
for i in enumerate(items):
for i, item in enumerate(items):
Enumerate hands back a pair, not a number. With one name you get the whole tuple — (0, "a") — and the first line of output gives it away.
Loops inside loops
Walk a grid.
- The inner loop finishes completely for every single pass of the outer one.
- So three outer passes over four inner ones is twelve passes in total. The work multiplies, it does not add.
- Two levels are readable. Three is usually a sign the middle part wants to be a function.
The mistake you are about to make
three levels of nesting
pull the middle level into a function
The work multiplies rather than adds: three passes of four is twelve. Two levels still read; three almost always means the middle one wants a name.