A light look at lists and looping

What’s a list?

So far, we have discussed three of Python’s data types: integers (int), floating-point numbers (float), and strings (str). Python also includes a type called a list which is, appropriately, a list of other values. Lists are created by writing a comma-separated sequence of elements in square brackets. Each of these elements is simply the Python code for another value, like so:

[1, 3, 5, 7]

The above is a list of the first four odd natural numbers. Elements of a list may be any legal Python expression. For instance, all of the following are lists:

[1+2, 3+4, 5+6]      # equivalent to the list [3,7,11]
[1.0, 3.5, 2.0]      # floats may be members of lists
["Ann", "Bjorn"]    # so can strings
[[1, 3, 5], [2, 4, 6]]  # this is a list of lists!

We discuss lists in greater detail later. For now, lists are most interesting because we can “loop over them.” That leads us to our next question...

What’s a loop?

The code examples presented so far consist of a series of statements which are executed in order. For instance, consider the following source:

print("How are you today?")
mood = raw_input()
print("Me too!")

When executed, this program will print a prompt (How are you today?), wait for the user to answer the question, and then print a follow-up message. These statements occur in the order they occur in the source code and each of them will only run once. In a sense, the code runs in a straight line from the top of the file to the bottom.

By contrast, a loop is a piece of code which may execute many times (or perhaps even not at all). One such loop is the for loop, an example of which appears in the following code:

for name in ["Alice", "Bjorn", "Cayman", "Duanphen", "Esfir", "Farah"]:
    print("I know " + name + ".")
    print("%s is a friend of mine." % (name))
print("Those are the people I know.")

In the above code, for and in are keywords in the Python language. Between them, name describes the name of a variable. After in, a list must appear, followed by a colon (:). Finally, note that two print statements beneath the for loop are indented, forming what is known as the body of the loop.

When the for loop is executed, Python will run the entire body of the loop once for each element in the for loop’s list. Each time the body runs, the variable (here, name) will be set to that element. So the steps of the above program are:

  1. Set name to "Alice".
  2. Execute both of the statements in the body of the loop.
  3. Set name to "Bjorn".
  4. Execute both of the statements in the body of the loop again.
  5. Continue the above process until we have set name to "Farah" and run the body of the loop.
  6. Having completed the for loop, now execute the final print statement.

The output of the program is therefore:

I know Alice.
Alice is a friend of mine.
I know Bjorn.
Bjorn is a friend of mine.
I know Cayman.
Cayman is a friend of mine.
I know Duanphen.
Duanphen is a friend of mine.
I know Esfir.
Esfir is a friend of mine.
I know Farah.
Farah is a friend of mine.
Those are the people I know.

Of course, we can achieve the above output using straight-line code as well, but it is far more tedious!

range

In the above example, the for loop keeps the code small but doesn’t let us do anything we couldn’t do without it. for loops become more interesting if we give them lists created using the range function.

The range function is built into Python and creates a list of numbers over a given range. For instance, range(5) creates a list of five numbers: [0,1,2,3,4]. Because range produces a list, we can use range to create very large loops:

for number in range(1000):
    print(number)

These two lines execute the print statement a total of 1000 times!

The range function can take any int value, even one from user input. If we want to give the user control of how many times we run our loop’s body, for instance, we might write a program like this:

total_str = raw_input("How many numbers should I print? ")
total = int(total_str)
for number in range(total):
    print(total)

Now, the number of times the print statement runs is up to the user.

The range function can be called in different ways. When given a single integer, the range function creates a list starting from 0 and going up to (but not including) the number it was given. As we’ve seen above, range(5) produces [0, 1, 2, 3, 4]. When given two integers, the list starts at the first integer and goes up to (but does not include) the second; range(2, 8) produces [2, 3, 4, 5, 6, 7]. Finally, range can be given a third integer to jump further between numbers. For example, range(3, 9, 2) produces [3, 5, 7]: it started from 3, and then gave each number that was 2 more than the last (but did not include 9).

Accumulators

One helpful technique to use with loops is to create a variable called an accumulator. An accumulator variable is like any other variable, but it is used to gather up (accumulate) information as we run the loop.

Consider a program that adds up all of the numbers from 0 to some number given by the user. That is, if the user provides 8, it will produce 36 (which is the result of computing 0+1+2+3+4+5+6+7+8). How would we write such a program? We can’t loop to create more + operations; our loop can only run a fixed list of statements over and over again.

This problem is best solved by an accumulator which will track the total we have added so far in the program. At the beginning of the program, we set the accumulator to 0 (because we haven’t done any addition yet). Then, the loop body adds another number to the accumulator each time it runs.

last_number_str = raw_input("Sum up to what number? ")
last_number = int(last_number_str)
sum = 0  # this is our accumulator
for number in range(0, last_number+1):  # +1 to include last_number itself
    sum = sum + number  # increases the sum variable by number
print("The sum of those numbers is: %d" % (sum))

We set the sum accumulator to 0 above because 0 is the unit of addition: it is the value which has no effect when it is added to another number. To compute the factorial of a number (rather than the summation), our loop would need to multiply the accumulator and so its initial value would be 1 (the unit of multiplication).

Glossary

body
The part of a loop statement which may run many times (or not at all).
element
A value which appears in a list.
list
A type of value which contains other values, called elements, in some order.
loop
Code which may execute many times (or not at all).

Exercises

  1. One example from this chapter prints all of the numbers from 0 to a number that the user provides. Write a program that prints all of the odd numbers from 0 to a number that the user provides.

  2. What is the output of the following for loops?

    for i in range(0):
      print("hello")
    
    for i in []:
      print("goodbye")
    
  3. Some of the above loops use lists directly (e.g. [1, 2, 3]) or use the range function. Do the following work?

    x = range(5)
    for i in x:
      print("hello")
    
    x = 5
    for i in x:
      print("hello")
    
  4. Technically, for loops work with any sequence in python. A string is a sequence. What is the output of the following loop?

    mystr = "Swarthmore"
    for i in mystr:
      print(i)
      print("--------------")