for, while, range & break/continue
Repeat work over collections and ranges, accumulating a result.
Why loops are the workhorse of real code
Almost nothing useful happens exactly once. You process every row in a file, retry a request until it succeeds, sum a column, or scan a list for the values you care about. A loop is how you say "do this for each of these" without copying the same line a thousand times. In data and backend work, most of your logic lives inside some loop over records, so knowing exactly how each loop starts, advances, and stops is core mechanics, not trivia.
for: run the body once per item
A for loop binds a variable to each element of a collection in turn and runs its body:
for name in ["Ada", "Sam"]:
print(name) # Ada, then Sam
The loop variable (name) is reassigned each pass. When the collection is exhausted, the loop ends on its own. You never manage an index by hand unless you actually need one.
range: count without building a list
range(start, stop) produces the integers from start up to but not including stop:
| You write | You get | How many items |
|---|---|---|
| range(4) | 0, 1, 2, 3 | 4 |
| range(1, 4) | 1, 2, 3 | 3 |
| range(0, 10, 2) | 0, 2, 4, 6, 8 | 5 |
| range(4, 0, -1) | 4, 3, 2, 1 | 4 |
| range(4, 4) | nothing | 0 |
| range(0, 10, -1) | nothing | 0 |
for i in range(1, 4):
print(i) # 1, 2, 3
That excluded stop is the single most common source of off-by-one bugs. To count 1 through n inclusive, you need range(1, n + 1). With one argument, range(n) starts at 0 and gives n values: 0, 1, ..., n - 1.
The accumulator pattern
Most "compute a result over many items" problems share one shape: start a variable at a neutral value, then update it every pass. The demo below sums 1 through 5:
total = 0
for i in range(1, 6):
total = total + i # total += i does the same
print(total) # 15
The starting value matters. total = 0 is the correct answer when nothing is added, so if the range is empty the loop body never runs and you get 0 back. That is exactly the n = 0 case you will handle.
To count instead of sum, keep a counter and bump it only when a condition holds. The even test uses the modulo operator %, which gives the remainder of a division:
count = 0
for n in [1, 2, 3, 4]:
if n % 2 == 0: # remainder 0 means even
count += 1
print(count) # 2
while, break, continue
A while loop repeats as long as its condition is True, so something inside must move toward making it False or it runs forever:
n = 3
while n > 0:
print(n) # 3, then 2, then 1
n = n - 1 # move toward the exit, or it loops forever
break exits the loop immediately, and continue skips the rest of the current pass and jumps to the next one:
for n in nums:
if n < 0:
continue # skip this value, keep looping
if n > 100:
break # stop the whole loop now
process(n)
Pitfalls
- Off-by-one:
range(1, n)stops atn - 1. Summing1tonneedsrange(1, n + 1). - Infinite
while: if you forget to update the variable in the condition, the loop never ends. Always change state that moves toward the exit.
Interview nuance: range is a lazy sequence, not a list. range(1_000_000_000) costs constant memory because it stores only start, stop, and step and computes each value on demand, rather than materializing a billion integers. That is why looping with range(n) is O(n) time but O(1) extra space, while list(range(n)) would allocate all n values up front. Interviewers use this to check whether you understand that iterating over data is not the same as storing it.
total = 0
for i in range(1, 6):
total = total + i
print(total) # 15Apply
Your turn
The task this lesson builds to.
Implement sum_to(n): return the sum of all whole numbers from 1 up to and including n.
For n = 5 that's 1 + 2 + 3 + 4 + 5 = 15. For n = 0, return 0.
3 hints and 4 automated checks are waiting in the workspace.
Practice
Make it stick
A second problem on the same idea, so it survives past today.
Implement count_evens(nums): return how many numbers in the list nums are even.
For [1, 2, 3, 4] return 2.
3 hints and 4 automated checks are waiting in the workspace.