02: The For Loop

Introduction

In all areas of business, there are often times where we need to repeat a single task several times. Sometimes, we have to do something two or three times before we can really say we’re “done”. Even more often, however, are times when we must repeat ourselves hundreds or thousands of times!

Let’s say we have a simple example, where we must start with the number 20 and must subtract one from it and print the result, five times, until we are left with the number 15. This is a pretty simple example mathematically, but how do we implement it in Python?

20 - 1 - 1 - 1 - 1 - 1 = 15.

There are a few ways to do this. The most obvious is to simply tell Python to subtract one, then repeat that ten times. That looks something like this:

myNumber = 20 
print myNumber 
myNumber = myNumber - 1 
print myNumber 
myNumber = myNumber - 1 
print myNumber 
myNumber = myNumber - 1 
print myNumber 
myNumber = myNumber - 1 
print myNumber 
myNumber = myNumber - 1 
print myNumber

This gives us the output we’re looking for.

20 
19 
18 
17 
16 
15

This could work, but what if we wanted to repeat the process 100 times? 10,000 times? We need to find a better way.

The DRY Method

The DRY method is an important concept for anyone writing code. It’s simple in theory, and Python has everything you need

Don’t
Repeat
Yourself

By following this rule, we can be confident that we are never writing more code than is necessary. In the example above, we saw that repeating ourselves took 12 lines of code to solve a very simple problem. Can we do it in less? Luckily, programming languages come with just the thing we need.

The FOR Loop

Python’s FOR loop is essential to successful Python programming. The structure of a FOR loop looks something like this:

for i in range(x, y): 
    # Do something here

The section “do something” can be almost anything! Any process or algorithm we can write in Python, we can have Python repeat by putting it inside this loop.
Here’s a breakdown of what the variables really mean:

i   The index value. moves through some set of values and updates automatically with each loop.
x   The lower limit of the range.
y   The upper limit of the range.

The Range

To get an idea of how this loop is working, let’s look at a very simple example.

for i in range(1, 3): 
    print "Hello World."

And the output:

Hello World. 
Hello World.

This is almost what we expected, but why didn’t the loop print 3 times? Well it ends up that this structure of the for loop is using Python’s built in range(x, y) function. This function has a catch. The range that you enter will include the lower limit, but exclude the upper limit. This is incredibly important to remember during the labs, as this is one of the most common errors in FOR loops.

So to clarify, here’s some more examples of ranges:

range()output
range(1, 5)[1, 2, 3, 4]
range(0, 5)[0, 1, 2, 3, 4]
range(x, y)[x, x+1, x+2 … y-1]
range(x, y + 1)[x, x+1, x+2 … y-1, y]
If this is still unclear, please ask, or refer to your textbook!

It is important to remember that range(x, y) can include a set of any integers (x, y), such that x < y.

The Index Value

The index value, often i (but it can be anything), is a very important part of our FOR loop. Every time it “loops”, i changes. More specifically, the loop will repeat once for every value in the range, and i will take on each value inside the range in order.

For range(1, 5) we have [1, 2, 3, 4]. Thus, the loop will run four times.

  • During the first loop, i is 1
  • During the second loop, i is 2
  • During the third loop, i is 3
  • During the fourth loop, i is 4

We can see how this works in a Python FOR loop:

for i in range(1, 5): 
    print i

And the output:

1 
2 
3 
4

Using the FOR Loop

Let’s take a look at some applications of the FOR loop. Let’s start by revisiting the example from earlier, but using a loop.

First, we define our variable:

myNumber = 20

Then, we set up the loop:

myNumber = 20 

for i in range(x, y): 
    # Do something

We know the loop must run five times, so let’s pick an appropriate range:

myNumber = 20 

for i in range(1, 6): 
    # Do something

And each loop will subtract one from the value we’ve defined:

myNumber = 20 

for i in range(1, 6): 
    myNumber = myNumber - 1

Let’s take a look at the output:

19 
18 
17 
16 
15

Perfect. Note that the order of commands inside the FOR loop is important. Here, we see that the number 20 was not printed, because the subtraction comes before the print statement inside the FOR loop.

FOR loops can also manage lists in an even easier way! The loop can iterate through a list, and work on each element in the list individually. Let’s take a look at this list:

fruitList = ["Apple", "Pear", "Orange", "Mango", "Strawberry"]

Say we wanted to print each element in the string. We can do that as it was done above:

for i in range(len(fruitList)):
    print fruitList[i]

But this is messy and using index values like this can be confusing, especially when we have lists of lists. Here’s how we can tell Python to automatically grab another element in the list each time the loop runs:

for fruit in fruitList: 
    print fruit

You’ll notice the output in both cases is the same. The second method is much easier, and basically tells Python “for each element in this list, perform this function”. That way, we don’t have to worry about the size of the list or our range values (especially if the size of the list is changing inside the loop).

However, it is important to remember that the second method does not directly work with the list. For example, let’s look at these two loops:

fruitList = ["Apple", "Pear", "Orange", "Mango", "Strawberry"] 
for i in range(len(fruitList)): 
    fruitList[i] = "I don't like fruit."

and

fruitList = ["Apple", "Pear", "Orange", "Mango", "Strawberry"] 
for fruit in fruitList: 
    fruit = "I don't like fruit."

What do you think the outputs of these should be? Likely, you would expect our fruitList to be equal to:

["I don't like fruit.", "I don't like fruit.", "I don't like fruit."]

This is true for the first case, but not for the second! The result for the second (simpler) loop is:

["Apple", "Pear", "Orange", "Mango", "Strawberry"]

You can see here that the list was not actually changed in the second loop. Can you figure out why?

It ends up that it has to do with how we access the values in our loop. For the first loop, we are using a number i to determine when our loop should terminate. As soon as i becomes out of our range(), the loop stops. We then access our loop directly by index in the form list[index]. This means when we make a change to the list, we are accessing the list directly.
The second method uses a temporary variable fruit. Every time the loop runs, Python stores the next element in the list to fruit. This means when we make changes to fruit, we are only making changes to that temporary variable, and NOT directly to the list.

To edit a list element, you must always access the list directly at some index (list[index])


Common Mistakes

There are a few common mistakes that people make when using FOR loops. I’m going to cover a few of the important ones that I have seen in the labs.

1. Naming Variables

In Python, it is very easy to save over information. If you store a variable, you can easily rewrite its value. For this reason, it is important that we use different (and clear) variable names.

For example, let’s look at the following code (don’t worry too much about what the code is doing):

x = 1 
y = 10 
z = 100 

for x in range (x, y): 
    z = z - x - y 

print z

Hopefully it is clear why this code is dangerous. First, our variable names are not clear. What are x, y, and z? If another programmer (or a TA!) looked at your code, they would have a hard time understanding what you’re trying to do.

The next problem we come across is rewriting the value of x. Because this is a simple example, we can see how x is the lower limit of the range. The problem is that we are writing over this value each time the loop runs, because we have defined it as our index value!

Lastly, because the variables are not named correctly, our mathematical formula becomes very confusing. We can see here also how the variable x can be so dangerous. If our intention was for x to always be equal to one, we would get an incorrect answer, as x will change during every loop iteration.

Let’s see how we can improve this code.

lowerLimit = 1   # 
upperLimit = 10  # Appropriate Names
myNumber = 100   # 

for i in range (lowerLimit, upperLimit): # Correct use of index value 
    # New mathematical formula. 
    myNumber = myNumber - lowerLimit - upperLimit 

print myNumber

2. Incorrect Range Values

This tutorial covers ranges earlier on. Still, I find it important to mention that a lot of students struggle to define their range values correctly.

An easy way to make sure you get it right is just to make sure that if you want including all numbers between a number a and a number b, define your FOR loop range like this:

for i in range (a, b + 1):

Since Python includes the lower limit, but not the upper limit, this will give you all numbers between and including a and b.

3. Order of Loop Operations

Recall from the earlier example that the number 20 was not printed because the print statement happened after we subtracted one from our number. This presents a common problem, where the values we receive during mathematical operations can change depending on the order of our operations.

For example:

x = 10 
y = 0 

for i in range(1, 10): 
    x = x - 1 
    y = x - 1 
    print y, " ", x

Gives us the output:

8 9 
7 8 
6 7 
5 6 
4 5 
3 4 
2 3 
1 2 
0 1

We can see that this is because the value of “y” is determined after we subtract from “x”. Alternatively, if we were to write:

x = 10 
y = 0 

for i in range(1, 10): 
    y = x - 1 
    x = x - 1 
    print y, " ", x

We would get:

9 9 
8 8 
7 7 
6 6 
5 5 
4 4 
3 3 
2 2 
1 1

This is a difficult problem to describe. Hopefully this is a clear example. Please let me know if further discussion is required for this concept.