For loops

It is possible to make Python repeat certain lines of code using loops. The ability to run a line of code multiple times is the first large step on your road to making your code more structured and reusable.

Imagine we have three strings in a list that we want to print. We could start by calling print three times to create a program like:

loop.py
my_words = ["Jean", "Golding", "Institute"]
print(my_words[0])
print(my_words[1])
print(my_words[2])
Jean
Golding
Institute

This printed the output we want. But you may feel that repeating the same call to print is wasteful code, particularly if we want to repeat the same operation for many elements. If we can manage to write that line only once then we could save ourselves some typing and potentially make the code easier to read!

FOR EACH word IN my_words
    DO SOMETHING WITH word    

We can write a for loop in Python which will perform a task once for each word in our list:

loop.py
my_words = ["Jean", "Golding", "Institute"]

for word in my_words:
    print(word)
Jean
Golding
Institute

Even in this tiny example, we have ve taken a script that was four lines of code and have reduced it to three lines, and more interestingly the same loop will work no matter how many items there are in the list my_words.

This maps to real life where you may want, for example, to pay for each item on your shopping list. Another way of saying that could be “for each item on my shopping list, add its price to my total”, or as you would write that in Python:

total = 0
for item in shopping_list:
    total = total + item.price
Exercise 1

Edit loop.py to have a different number of words in the list.

  • Does it work if you put numbers (i.e. integers or floats) in there as well?
  • What happens if the list my_words is empty? (hint: empty lists look like [])
Adding more items to the list makes the loop go around more times
loop.py
my_words = ["Hello", "Python", "Goodbye", "Python"]

for word in my_words:
    print(word)
python loop.py
Hello
Python
Goodbye
Python
A list with a mixture of data types can be printed witout issue
loop.py
my_words = ["Hello", "Python", 404, "Goodbye", "Python", 42]

for word in my_words:
    print(word)
Hello
Python
404
Goodbye
Python
42
Looping over an empty list does not print anything
loop.py
my_words = []

for word in my_words:
    print(word)
for statement syntax
A for statement has an scaffolding, the parts of the line which must always be the same and tell Python that you’re trying to make a loop, composed by the word for, the word in and the colon (:) at the end of the line. These must always be there and in that order:
 ↓        ↓         ↓
for word in my_words:
    print(word)
Once the scaffolding is in place, you can place between it the things that you care about. The first thing to think about is the variable that you want to loop over. In our case we want to loop over the list my_words because we want to print every item in that list:
                ↓
for word in my_words:
    print(word)
Now we need to decide what name we want to give temporarily to each item as we get to it. As with any variable naming, it is important that we choose a good name which describe a single object from the list. For example, if we’re looping over all students in a class then we could call the variable student or if we’re looping over a list of ages then we could call the variable age. Here, since we’re looping over a list of generic words, we name our variable word:
      ↓
for word in my_words:
    print(word)
Finally, if we want the loop to actually do something then we need to give the loop a body. The body is the lines of code that are going to be repeated. They can be any Python code but it is only within the body of the loop that we can refer to the loop variable word. As with if, Python uses indentation to decide what is in the body of the loop and what is not. Remember that it will only repeat the code in the body. All code in the body must be indented relative to the word for by four spaces.
for word in my_words:
    print(word)
  ↑
indentation

If we want to write more code after the end of a loop, we have to make sure that it is not indented. So this code:

loop.py
my_words = ["Hello", "Python"]

for word in my_words:
    print(word)

print("...Goodbye")

will print:

Hello
Python
...Goodbye

On the contrary, the below code will print ...Goodbye in each iteration. This is because it was inside the body of the loop since it was indented.

my_words = ["Hello", "Python"]

for word in my_words:
    print(word)

    print("...Goodbye")
Hello
...Goodbye
Python
...Goodbye

What can we loop over?

A lot of the power of loops comes from being able to put a lot of different types of data.

Most simply, instead of putting a variable name there, you can put a list directly:

loop.py
for word in ["Hello", "Python"]:
    print(word)

As well as lists we can put anything which Python considers iterable. For now we haven’t come across many of those but as we keep learning we’ll discover many more. One that we have already come across is strings: looping over a string will always give you one letter at a time.

loop.py
phrase = "Hello Python"

for letter in phrase:
    print(letter)
Exercise

Experiment with loop.py and make it loop over both lists and strings.

Starting with the same list we used before, each item in the list gets printed on its own line.

loop.py
words = ["Hello", "Python"]

for word in words:
    print(word)
Hello
Python

On the contrary, if we loop over a string we see that each character gets printed on its own line.

loop.py
phrase = "Hello Python"

for letter in phrase:
    print(letter)
H
e
l
l
o
 
P
y
t
h
o
n

Loop over a range of numbers

There’s a built in function in Python called range which provides you with numbers (integers) in a range. If given one number as an argument it will give you integers, starting from zero and going up to, but not including, the number you gave as an agument. We can put this call to the range function directly into our loop as the object to loop over and it will print:

for number in range(5):
    print(number)
0
1
2
3
4

The range function can also be given two arguments, in which case, the first argument is the number to start counting from and the second argument is used as above:

for number in range(10, 13):
    print(number)
10
11
12