for
Loops#
Turn off the GitHub Copilot AI assistant so you can focus on learning Python using your HI (human intelligence). Click the
Deactivate Copilot
button in the bottom right of VS Code, if it is currently activated.
Questions:#
How can I make a program do things repeatedly?
Learning Objectives:#
Explain what for loops are normally used for.
Trace the execution of a simple (unnested) loop and correctly state the values of variables in each iteration.
Write for loops that use the Accumulator pattern to aggregate values.
A for
loop executes commands once for each value in a collection#
Doing calculations on the values in a list one by one is as painful as working with many individual variables rather than a list or dictionary (e.g.,
life_exp_1900
,life_exp_1920
, etc. rather thanlife_exp = [48.1, 56.6, 64.0, 71.0, 75.2, 79.2]
A for loop tells Python to execute some statements once for each value in a list, a character string, or some other collection
The
for
command means, “for each thing in this group, do these operations”
for number in [2, 3, 5]:
print(number)
The for
loop above is equivalent to:
print(2)
print(3)
print(5)
and the for
loop’s output is:
for number in [2, 3, 5]:
print(number)
2
3
5
However, the
for
loop is scalable to any length input.This makes it flexible, because we might not know in advance how many inputs we want to operate on.
A for
loop is made up of a collection, a loop variable, and a body.#
In our example:
for number in [2, 3, 5]:
print(number)
The collection,
[2, 3, 5]
, is what the loop is being run on.The loop variable,
number
, is what changes for each iteration of the loop.This keeps track of where we are in the loop — the “current thing”
The body,
print(number)
, specifies what to do for each value in the collection.
The first line of the for
loop must end with a colon, and the body must be indented#
The colon at the end of the first line signals the start of a block of statements.
Python uses indentation to show nesting (this is different from other languages, which often use explicit markers for the start and end (e.g.,
{}
orbegin
/end
) of a nesting.Any consistent indentation is legal, but almost everyone uses four spaces.
for number in [2, 3, 5]:
print(number)
Indentation is always meaningful in Python#
After a
for
statement, Python expects at least one indented line with the body of the for loopThe end of the body of a for loop is indicated by a line of code that is not indented
It’s good coding style (although not required) to put a blank line after the end of the body of a for loop, before the next line of code that’s not in the for loop
For example:
for country in ['Canada', 'USA', 'Mexico']:
print(country)
print('All done printing country names')
Canada
USA
Mexico
All done printing country names
Because indentation is always meaningful, the code below generates an error:
life_exp_1900 = 48.1
life_exp_1920 = 56.6
life_exp_1900 = 48.1
life_exp_1920 = 56.6
This error can be fixed by removing the extra spaces at the beginning of the second line.
life_exp_1900 = 48.1
life_exp_1920 = 56.6
Question#
Is an indentation error a syntax error or a runtime error?
Solution#
A Python IndentationError
is a syntax error. Programs with syntax errors cannot be started.
A program with a runtime error will start but an error will be thrown under certain conditions.
Loop variables can be called anything.#
As with all variables, loop variables are:
Created on demand
Meaningless: their names can be anything at all
So the following are valid
for
loops, but not great loop variable names (unless in the first example your data actually concern kittens):
for kitten in [2, 3, 5]:
print(kitten)
2
3
5
for ytrjmn in [2, 3, 5]:
print(ytrjmn)
2
3
5
As always, clear and meaningful variable names are best practice
The collection can be a list, dictionary, etc. that was defined previously#
life_exp = [48.1, 56.6, 64.0, 71.0, 75.2, 79.2]
for e in life_exp:
print(e)
48.1
56.6
64.0
71.0
75.2
79.2
Strings can also be used as the collection, in which case the loop will step through each character of the string:
for c in 'SURGE':
print(c)
S
U
R
G
E
The body of a loop can contain many statements.#
primes = [2, 3, 5]
for p in primes:
squared = p ** 2
cubed = p ** 3
print(p, squared, cubed)
2 4 8
3 9 27
5 25 125
Use range
to iterate over a sequence of numbers#
This is an easy way to generate a sequence of numbers to make looping over large ranges more efficient
range(n)
is the numbers 0 … n-1recall that Python counts from zero
as with slicing,
range()
goes up to, but does not include, the last value
for i in range(10):
print(i)
0
1
2
3
4
5
6
7
8
9
If we provide two arguments to
range()
, the first is the start and the second is the end of the range:
for i in range(10, 15):
print(i)
10
11
12
13
14
Although the
range()
function can substitute for typing out a list, it does not actually produce a listThe numbers are produced on demand to make looping over large ranges more efficient. We can see this by printing the result of calling the
range()
function:
print(range(10))
range(0, 10)
…or by printing its type:
print(type(range(10)))
<class 'range'>
The “accumulator” pattern turns many values into one#
A common pattern in programs is to:
Initialize an accumulator variable to zero
Update the variable with values from a collection.
The code below sums the integers 1-10:
total = 0
for number in range(1, 11):
total = total + number
print(total)
55
Note that we specify a range of 1-11 because the
range()
goes up to, but does not include, the ‘end’ number
Read
total = total + number
as:Add the value of
number
to the current value of the accumulator variabletotal
.Assign that to
total
, replacing the current value.
Accumulators can also be empty lists#
This is where empty lists and the .append()
method can be really useful - we can initialize an empty list and the append to it each time through the loop:
output = []
for i in range(10):
output.append(i * 2)
print(output)
[0, 2, 4, 6, 8, 10, 12, 14, 16, 18]
List comprehension#
List comprehension is a special kind of
for
loop that you can use to create a listThis can be a very powerful and compact way of doing things
For example, the following code creates a list of values from 1 to 10 in a single line of code:
[x for x in range(1, 11)]
[1, 2, 3, 4, 5, 6, 7, 8, 9, 10]
List comprehension can be very useful if you want to apply some operation to every value in a list
For example, let’s say we had a set of times in seconds, and we wanted to convert them to milliseconds (thousandths of a second):
time_sec = [0.19859864, 1.35544082, 0.81298099, 1.80873061, 0.78908326,
1.40242708, 0.39563692, 1.91673302, 1.07524985, 1.02169021]
time_ms = [t * 1000 for t in time_sec]
print(time_ms)
[198.59864, 1355.44082, 812.98099, 1808.73061, 789.08326, 1402.4270800000002, 395.63692, 1916.73302, 1075.2498500000002, 1021.6902100000001]
The equivalent for
loop would require three lines of code:
time_ms = []
for t in time_sec:
time_ms.append(t * 1000)
print(time_ms)
[198.59864, 1355.44082, 812.98099, 1808.73061, 789.08326, 1402.4270800000002, 395.63692, 1916.73302, 1075.2498500000002, 1021.6902100000001]
We can put multiple operations in a list comprehension, for example to also round our milliseconds down to whole numbers:
time_ms = [round(t * 1000) for t in time_sec]
print(time_ms)
[199, 1355, 813, 1809, 789, 1402, 396, 1917, 1075, 1022]
Lambda Functions and Mapping#
Yet another way of performing an operation over a collection, is by combining map()
and lambda
functions. Recall that functions are Python commands like print()
and type()
. A Python function is actually a program that is run when you execute the function.
lambda
functions are a way of creating your own very small functions, on the fly, to perform a specific operation or combination of operations. Lambda functions take variables as input and return a value (the results of the operations it performs). A lambda function is composed of:
the statement
lambda
the argument(s) — the variable(s) you pass to the operations in the lambda function
a colon
the expression (operations you want the function to perform on the arguments)
For example, we-writing the above code to convert seconds to milliseconds and round to integers as a lambda function would be:
lambda t: round(t * 1000)
Mapping#
As with the print()
or round()
functions, with a lambda function you need to pass something to it as an argument for it to operate on. The variable t
in the lambda function above represents the argument passed to the lambda function. We can pass a collection to a lambda function, so that it will be applied to each item in the collection.
The map()
function is used to apply a lambda function to a collection, instead of using a for
loop
map()
takes two arguments:
the function you want to apply
the collection you want to apply it to
The code below maps the convert-to-milliseconds-and-round function to the time_sec
list:
time_ms = map(lambda t: round(t * 1000),
time_sec)
However, the result is not a list, but a Python `map’ object:
print(type(time_ms))
print(time_ms)
<class 'map'>
<map object at 0x103dd5660>
This is because the result of the map()
function is a mapping between the lambda function and the collection. That is, it specifies how a function is applied to the collection, but it doesn’t actually apply the function until you ask it to generate output. We can do this by telling Python to format the result of the mapping as a list with the list()
function:
time_ms = list(map(lambda t: round(t * 1000),
time_sec))
print(time_ms)
[199, 1355, 813, 1809, 789, 1402, 396, 1917, 1075, 1022]
Which to use?#
for
loops are the most general, multipurpose way of performing an operation over many itemsfor
loops are quite explicit compared to list comprehensions or mapped lambda functions, and a good way to start tackling any problemThe body of
for
loops can be of any length, whereas list comprehensions and lambda functions are best used with only one or a few operationsList comprehensions result in lists, which is not always what you want out of a
for
loopList comprehensions are generally faster than
for
loops, for creating listsLambda functions will become useful later in the course, as we start working with larger data sets. Stay tuned!
Exercises#
Tracing Execution#
In the Markdown cell below (not code!) trace the execution of the for
loop as it would run. That is, type what you expect would be the values of total
and c
each time through the loop. Use a separate line for each pass through the loop.
total = 0
for c in 'tin':
total = total + 1
An interesting thing to note in this example is that we never use the looping variable (c
) inside the loop; we only use it to control how many times we go through the loop. It’s a bit odd to use a string to define the number of times we want to perform an operation (since we’re not operating on the string), but it’s entirely valid Python code.
Reversing a String#
Fill in the blanks in the program below so that it reverses the order of the letters in original
(Hint: remember that you can concatenate strings in Python with the +
operator)
original = 'semordnilap'
result = ____
for char in original:
result = ____
print(result)
Click the plus to show the answer
original = 'semordnilap'
result = ''
for char in original:
result = char + result
print(result)
Practice Accumulating#
Fill in the blanks in each of the programs below to produce the indicated result.
1. Print the total number of characters in all of the words in the list#
(Correct answer is 12)
total = 0
for word in ['red', 'green', 'blue']:
____ = ____ + len(word)
print(total)
Click the plus to show the answer
total = 0
for word in ['red', 'green', 'blue']:
total = total + len(word)
print(total)
2. Print a list of the lengths of each word in the list#
(correct answer is [3, 5, 4]
)
lengths = ____
for word in ['red', 'green', 'blue']:
lengths.____(____)
print(lengths)
Click the plus to show the answer
lengths = []
for word in ['red', 'green', 'blue']:
lengths.append(len(word))
print(lengths)
3. Concatenate all of the words in the list into one string#
(correct answer is "redgreenblue"
)
words = ['red', 'green', 'blue']
result = ____
for ____ in ____:
____
print(result)
Click the plus to show the answer
words = ['red', 'green', 'blue']
result = ''
for word in words:
result = result + word
print(result)
4. Create acronym: [“red”, “green”, “blue”] = “RGB”#
Write all the code this time!
Hint: Python as a .upper()
method that works on characters and strings
Click the plus to show the answer
acronym = ''
for word in ['red', 'green', 'blue']:
acronym = acronym + word[0].upper()
print(acronym)
Cumulative Sum#
Reorder and properly indent the lines of code below
so that they print a list with the cumulative sum of data.
The result should be [1, 3, 5, 10]
.
cumulative.append(sum)
for number in data:
cumulative = []
sum += number
sum = 0
print(cumulative)
data = [1, 2, 2, 5]
Click the plus to show the answer
sum = 0
data = [1, 2, 2, 5]
cumulative = []
for number in data:
sum += number
cumulative.append(sum)
print(cumulative)
Identifying Item Errors#
Read the code below and try to identify what the errors are without running it.
Run the code, and read the error message. What type of error is it?
Fix the error.
seasons = ['Spring', 'Summer', 'Fall', 'Winter']
print('My favorite season is ', seasons[4])
Click the plus to show the answer
# This list has 4 elements and the index to access the last element in the list is `3`.
seasons = ['Spring', 'Summer', 'Fall', 'Winter']
print('My favorite season is ', seasons[3])
Summary of Key Points:#
A
for
loop executes commands once for each value in a collection.A
for
loop is made up of a collection, a loop variable, and a body.The first line of the
for
loop must end with a colon, and the body must be indented.Indentation is always meaningful in Python.
Loop variables can be called anything (but it is strongly advised to have a meaningful name to the looping variable).
The body of a loop can contain many statements.
Use
range
to iterate over a sequence of numbers.The accumulator pattern turns many values into one.
List comprehension is a powerful way to create lists using a
for
loop, in a single line of code.Mapped lambda functions are another way of performing an operation(s) over a collection of values
This lesson is adapted from the Software Carpentry Plotting and Programming in Python workshop.