Almost every algorithm in this course is a loop. This lesson shows the loops Python offers, and how to read a loop one line at a time.
Looping over values
A for loop runs its body once for each value in a list. Each time, the loop name (here x) refers to the next value. The body is the indented block under the for line.
Step through the figure. The highlighted line is the one about to run, and the table shows every name and its value. A row turns yellow when its value has just changed. Then switch to the comprehension and the while loop.
a = [3, 8, 5, 6]
evens = []
for x in a:
if x % 2 == 0:
evens.append(x)
print(evens)
| Variables | Value |
|---|---|
a | [3, 8, 5, 6] |
Line 1 makes the list.
Reading code this way, one line and one table of values at a time, is called tracing. It is slow, but it is the most reliable way to find out what a loop really does. When a practice test fails, trace the failing input by hand.
Looping over indices
Sometimes you need the index, not only the value. For example, to compare each value with the one before it. Then loop over range:
range(5) # 0, 1, 2, 3, 4
range(2, 5) # 2, 3, 4
range(0, 10, 3) # 0, 3, 6, 9
range(4, 0, -1) # 4, 3, 2, 1
for i in range(1, len(a)):
print(a[i] - a[i - 1]) # the change from the value before
range(start, stop) stops before stop, just like a slice. The loop above starts at 1, so that a[i - 1] always exists.
enumerate and zip
enumerate gives you the index and the value together. zip goes through two lists together, one item from each at a time, and stops at the end of the shorter one.
for i, x in enumerate(["BCT", "HWH", "MAS"]):
print(i, x) # 0 BCT, then 1 HWH, then 2 MAS
for x, y in zip([1, 2, 3], [10, 20, 30]):
print(x + y) # 11, then 22, then 33
while loops
A while loop repeats as long as a condition is true. Use it when you do not know in advance how many passes you need, as in the halving loop in the figure. Binary search is a while loop.
List comprehensions
A list comprehension builds a new list in one expression. These two pieces of code make the same list:
squares = []
for x in range(6):
squares.append(x * x)
squares = [x * x for x in range(6)] # [0, 1, 4, 9, 16, 25]
odd_squares = [x * x for x in range(6) if x % 2 == 1] # [1, 9, 25]
Read a comprehension from the for: “for each x in range(6), keep x * x”. Use one when the loop only builds a list. When the loop does more than that, a plain for loop is easier to read.
break and continue
break leaves the loop at once. continue skips the rest of this pass and goes on to the next value.
for x in a:
if x < 0:
continue # ignore negative values
if x == target:
print("found")
break # stop looking
A return inside a loop in a function also ends the loop, because it ends the whole function. Most search loops in this course end that way.
PYTH-2 counts as completed once you step through the figure to the last step.