{attention}
Finnish university students are encouraged to use the CSC Notebooks platform.<br/>
<a href="https://notebooks.csc.fi/"><img alt="CSC badge" src="https://img.shields.io/badge/launch-CSC%20notebook-blue.svg" style="vertical-align:text-bottom"></a>
Others can follow the lesson and fill in their student notebooks using Binder.<br/>
<a href="https://mybinder.org/v2/gh/geo-python/notebooks/master?urlpath=lab/tree/L3/for-loops.ipynb"><img alt="Binder badge" src="https://img.shields.io/badge/launch-binder-red.svg" style="vertical-align:text-bottom"></a>
In this lesson we introduce loops as a way of repeating parts of a Python program, such as iterating over all of the items in a list and performing a calculation using each item.
This lesson is inspired by the Software Carpentry group's lessons on Programming with Python.
In our last lesson we covered lists in Python, one form of a collection of values that can be referenced by a single variable. In this lesson we will learn how to use loops. Loops allow parts of code to be repeated some number of times, such as using a section of code to process each item in a list.
Let’s consider an example using the list below:
european_cities = ["Helsinki", "Paris", "Barcelona", "Uppsala"]
Suppose we want to check the name of each city in our list. We could use the index value for each city and do the following:
european_cities[0]
european_cities[1]
european_cities[2]
european_cities[3]
But this is a bad idea. Why? Well there are two reasons:
Let's see an example with a new list.
european_cities = ["Riga", "Rome", "Athens"]
european_cities[0]
european_cities[1]
european_cities[2]
european_cities[3]
Here we encounter an IndexError
because we have tried to access a value outside the range of values in the updated european_cities
list.
In such situations it is far more efficient to use a for
loop. Let's see an example.
european_cities = ["Amsterdam", "Brussels", "Lisbon", "Reykjavik"]
for city in european_cities:
print(city)
Not only is this shorter, but it is also more flexible.
Let's try printing out a different list of cities such as ['Detroit', 'Chicago', 'Denver', 'Boston', 'Portland', 'San Francisco', 'Houston', 'Orlando']
.
Still works, right?
us_cities = [
"Detroit",
"Chicago",
"Denver",
"Boston",
"Portland",
"San Francisco",
"Houston",
"Orlando",
]
for city in us_cities:
print(city)
for
loops in Python have the general form below.
for variable in collection:
do things with variable
Let's break down the code above to see some essential aspects of for
loops:
The variable
can be any name you like other than a reserved keyword
The statement of the for
loop must end with a :
The code that should be executed as part of the loop must be indented beneath the for
statement
There is no additional special word needed to end the loop, you simply change the indentation back to normal.
{hint}
`for` loops are useful to repeat some part of the code a *finite* number of times.
Source: https://www.bugmartini.com/comic/cats-eye/
Like many other programming concepts, the idea of looping through actions is something that is already perhaps more familiar to you than you think. Consider your actions during a given weekday. Many people have certain routines they follow each weekday, such as waking up, taking a shower, eating breakfast, and brushing their teeth. In Python code, we might represent such actions as follows:
for day in my_week:
wake_up()
take_shower()
eat_breakfast()
brush_teeth()
...
Note that my_week
would be a list of the days of the week, and the actions you take are represented as functions, such as wake_up()
.
Furthermore, by following this kind of list of repeating actions we're able to start the day effectively even before the first cup of coffee :).
Note that the variable used in a for
loop is just a normal variable. Thus, its value still exists after the loop has been run. Let's loop over the list of weather conditions below and print them to the screen. If you use weather
for the loop variable, what is its value after the for
loop has completed?
weather_conditions = [
"rain",
"sleet",
"snow",
"freezing fog",
"sunny",
"cloudy",
"ice pellets",
]
for weather in weather_conditions:
print(weather)
print(f"After the loop, weather is {weather}")
A loop can be used to iterate over any collection of values in Python. So far we have considered only iterating over lists, but we could also write a loop that performs a calculation a specified number of times by using the range()
function. Let's consider an example where we use a for loop with value
as the loop variable and range(5)
as the collection. What happens when you print value
at each iteration?
for value in range(5):
print(value)
In this case, we used a special function called range()
to give us a list of 5 numbers [0, 1, 2, 3, 4]
and then we printed each number in the list to the screen.
When given an integer (whole number) as an argument, range()
will produce a list of numbers with a length equal to the specified number
.
The list starts at 0
and ends with number - 1
.
You can learn a bit more about range by typing help(range)
.
help(range)
The program below will print numbers to the screen using the range()
function.
for i in range(...):
print(i)
Using the documentation that is produced when you run help(range)
, what values would you replace the ...
in the parentheses of the range()
function with to have the following output printed to the screen?
2
5
8
You can test your solution in the cell below and select your answer from the poll options at https://geo-python.github.io/poll/.
# Here's one possible solution
for i in range(2, 9, 3):
print(i)
Since we already know how to find the length of a list using the len()
function, we can now take advantage of this knowledge to make our for
loops more flexible. Let's start by doing something we have done earlier, printing out city names using a for
loop. However, this time we will also use the range()
function to print the cities.
african_cities = ["Dakar", "Addis Ababa", "Nairobi", "Cairo", "Rabat", "Kampala"]
for i in range(len(african_cities)):
print(f"{african_cities[i]} is at index {i} in the list.")
Let's see what is different now:
range()
function, the value assigned to the loop variable i
starts with 0
and increases by 1
each time through the loop.african_cities
list, we need to include the index value (e.g., african_cities[i]
. Here, the variable i
will be replaced by the current value assigned from the range()
function.{note}
The variable `i` is commonly used to denote the index variable in loops. Loops can sometimes occur with another loop (referred to as nested loops), in which case other index variables such as `j` or `k` may be used.
Good question. There are two common case where you might need to loop using index values:
enumerate()
that can help, but their use can be somewhat confusing for new programmers.cities = ["Helsinki", "Stockholm", "Oslo", "Reykjavik", "Copenhagen"]
countries = ["Finland", "Sweden", "Norway", "Iceland", "Denmark"]
As you can see we have 5 cities and 5 corresponding counties. Can you print out each pair using a single for loop?
for i in range(len(cities)):
print(f"{cities[i]} is the capital of {countries[i]}")
Cool. So as you can see, the index i
is used in this case to access each item in the two lists of cities and countries and allow us to print out the city/country pairs. We'll get more practice with this kind of thing in the exercises for this week.
{note}
In the example above, we used the length of the list `cities` in the `range()` function. We could just as easily used the list `countries` to define the values of `i` since both lists are the same length.
What output would the following program produce?
odd_numbers = [1, 3, 5, 7, 9]
even_numbers = [10, 4, 6, 8, 2]
for i in range(len(odd_numbers)):
print(odd_numbers[i] + even_numbers[i])
Try to think about the loop without running the code and then select your answer from the poll options at https://geo-python.github.io/poll/.
# Here's the solution
odd_numbers = [1, 3, 5, 7, 9]
even_numbers = [10, 4, 6, 8, 2]
for i in range(len(odd_numbers)):
print(odd_numbers[i] + even_numbers[i])