Skip to content

Loops



Why we need loops

Analogy

  • Say you have to print "Hello" a hundred times. You could write the line a hundred times. It would work.
  • Then someone asks for a thousand, and you would quietly change career.
  • A loop is how you say do this again without writing it again. Change 100 to 1,000,000 and the code does not get any longer.
  • And this is not about saving keystrokes. Almost every useful program is a loop over something: every row in a spreadsheet, every message in an inbox, every item in a list you are about to sort.

What is a loop?

Definition

A loop repeats a block of work while a condition holds.

Whatever the language and whatever the syntax, a loop is always the same four things: a start, a condition checked before every round, a body that does the work, and an update that moves you closer to stopping.

If a loop misbehaves, one of those four is wrong. Check them in that order.

STARTi = 0onceCONDITIONi < 5BODYprint(i)UPDATEi = i + 1every roundi takes each value in turn01234then 5 fails the check,and the loop is over

Notice where start sits. It runs once, outside the ring. A beginner who thinks it runs every round has written the infinite loop where the counter gets reset at the top of the body.


Which loop to use

SituationLoop
A known number of roundsfor
Every item in a listfor-each
Repeat until something changeswhile
Must run at least oncedo-while
Anything one loop can do the others can too. Pick the one that says what you mean.

for when the number of rounds is known before you start. The Java form shows all four parts on one line: for (int i = 0; i < 5; i++) is start, condition and update, with the body in braces.

for-each when you want each item and do not care about its position. No counter, no index, nothing to get wrong. Prefer it whenever you do not actually need the index.

while when you are waiting for something to become true and cannot predict how long that takes.

Code
i = 0while i < 5:  print(i)  i += 1        # forget this line and it never ends

A for loop keeps its four parts together in one place. A while loop scatters them, so you have to remember the update yourself. That is exactly why beginners write more infinite loops with while.

do-while checks the condition at the bottom, so the body always runs at least once. Perfect for menus: you always want to show the menu once before asking whether to show it again. Python has no do-while; the standard workaround is while True with a break at the bottom.


Why counting starts at zero

Because array positions start at 0. The first item is at index 0, and the last item in a list of five is at index 4. Starting your counter at 0 lines the two up perfectly.

Get used to it now, because it never goes away - and it is the source of the most common loop bug there is.


Off-by-one

Watch out

A list of three items has positions 0, 1 and 2. The length is 3 and the last valid position is 2.

Code
for i in range(len(items)):       # 0, 1, 2. correctfor i in range(len(items) + 1):   # 0, 1, 2, 3. crash

In C-style languages the same trap wears a different mask: i <= n does one round too many where i < n is correct.

The habit that saves you: whenever you write a loop, say out loud what the first value and the last value will be. Two seconds of checking prevents most of these.


break and continue

break leaves the loop entirely. Nothing after it in this round runs, and no further rounds happen. continue skips the rest of this round and jumps to the next one.

Code
for item in items:  if item == target:      print("Found it")      break          # stop searching, we are done

Both are useful. Both, used heavily, make a loop hard to follow. One break for an early exit is good; five scattered through a long body is a mess. And break only ever leaves the innermost loop.


Nested loops, and where slow code is born

A loop inside a loop. The inner one completes fully for every single round of the outer one, so three rounds outside and four inside is twelve.

Note

One loop over n items does n steps. A loop inside a loop does n × n.

The difference is brutal. With 1,000 items, one loop is 1,000 steps and a nested loop is 1,000,000.

When you meet bubble sort and see the phrase "O(n squared)", this is all it means: two nested loops over the same data.


Mistakes to watch for

Watch out

  • Forgetting the update in a while, creating an infinite loop.
  • Off-by-one. Using <= where you needed <.
  • Changing a list while looping over it. Items get skipped. Loop over a copy instead.
  • Assuming break exits all loops. It exits only the innermost one.
  • Putting work inside a loop that could sit outside it, doing the same job a thousand times.
  • Confusing break and continue. One leaves, one skips.

Quick recap

  • A loop repeats work without repeating code
  • Every loop is start, condition, body, update
  • for for a known count, for-each for items, while for an unknown count
  • break leaves the loop, continue skips to the next round
  • Infinite loops usually mean a missing or wrong update
  • Indexes start at 0, so the last one is length minus one
  • Nested loops cost n times n, and that is where slow code begins

Key takeaway

Start, condition, body, update. Every loop is those four, and every loop bug is one of them.