Looping Patterns With For Loops
When using for
loops, a few patterns show up frequently. If you learn these patterns — how to recognize them and how to code them —
it can help you translate problems into code more easily.
The Action Pattern
In the action pattern, we want to do something to (or with) each element of a list. This is the easiest pattern, because we can treat each item independently. All we need is a loop:
for each x in xx:
do something using x
Example: Printing the Elements of a List
for x in xx:
print(x)
Example: Printing the Elements of a List and Their Squares
for x in xx:
print(f"{x}, {x*x}")
The Accumulator Pattern
Unfortunately, most of the times we work with lists, we want to combine their items in some way. In the accumulator pattern, we want to build up a pattern using a collection of data.
Here is the pseudocode template:
initialize the accumulator
for each x in xx:
modify accumulator using x
(the final result is in accumulator)
The two tricky parts about the accumulator pattern are what to choose as the initial value for the accumulator, and how to update it. Here are two rules of thumb that can help you get started:
- When initializing the accumulator, think about what the result should be if the list was empty. In fact, if the list is empty, the
for
loop will be skipped, so the accumulator will be whatever you initialized it as. Common initial values are0
,[]
or""
, but you might have to be more careful, for example when you multiply numbers and don’t want to multiply with0
.
Example: Counting the Elements of a List
For this, count
is the accumulator, and at each step we add one to it.
count = 0
for x in xx:
count = count + 1
Example: Summing the Elements of a List
For this, sum
is the accumulator, and at each step we add x
to it.
sum = 0
for x in xx:
sum = sum + x
Example: Create a Dictionary with the Elements of a List and Their Squares
For this, d
is the accumulator, and at each step we update it by inserting key x
with value x*x
.
d = {}
for x in xx:
d[x] = x * x
Example: Taking the Maximum of the Elements of a List
For this, themax
is the accumulator, and at each step we update it with x
using the built-in function max
.
themax = xx[0]
for x in xx:
themax = max(themax,x)
Note that here initializing themax
is tricky, because the maximum of an empty list doesn’t really make sense. We initialize it to the first element of the list, which requires that the list is non-empty. If the list is empty, the code above will produce an error. You could also initialize themax
with some arbitrary number like 0
or -99999999
, but that can also be dangerous, for example when the list only contains only numbers that are even smaller.
The Accumulator Pattern with Logic
Sometimes, we don’t just want to combine the elements of a list, but also treat them differently depending on their value. This is where the accumulator pattern needs to be combined with some logic:
initialize the accumulator
for each x in xx:
if some condition:
modify accumulator using x
else (optional):
modify accumulator in a different way
(the final result is in accumulator)
Example: Keeping only Elements of a List Greater than 0
For this, filtered
is the accumulator, and at each step we only append x
if it is greater than 0.
filtered = []
for x in xx:
if x > 0:
filtered.append(x)
Example: Summing only Even Elements of a List
For this, sum
is the accumulator, and at each step we only add x
if it is even. Note that we can check if x
is even by writing x % 2 == 0
(read: “if we do integer division of x by 2, is the remainder 0?”).
sum = 0
for x in xx:
if x % 2 == 0:
sum = sum + x
Example: Taking the Maximum of the Elements of a List, Alternative Approach
For this, themax
is again the accumulator, but this time we do not use the built-in function max
. Instead, we use our own logic.
themax = xx[0]
for x in xx:
if x > themax:
themax = x