Iterating (a.k.a. Looping)
So we can now make lists and fill them with all sorts
of values. Now what? We need to process all those values in order
to extract something useful out of them.
How can we step through a list one element at a time?
Here we introduce one technique: the for
loop.
A for
loop fundamentally steps through all the elements
of an iterable entity, which is anything that has elements that can be
stepped through one at a time. This includes lists and strings, as we'll
see here. The beauty of a for
loop,
however, lies in the fact that it will also perform a given sequence
of operations for every element that it iterates through.
Let's try a very simple example:
-
numbers = [1, 6, 0, 3, 7] for number in numbers: print number
numbers
is placed in the
variable number
. The indented code, the loop body,
is performed for each value that number
takes on. So,
in this case, number
becomes 1, and that is printed, then
number
becomes 6, and that is printed, etc.
I.e., this prints each element of the list, from first to last.
We can take this idea to define a function to print the elements of whatever iterable is given to the function.
-
def print_elements(an_iterable): """Print each list value on a separate line.""" for element in an_iterable: print element print_elements(range(10)) print_elements(["Programming", "is", "fun!"] print_elements("Programming is fun!")
As you can see, this works regardless of the kinds of data in the input list. It also works on strings, rather than lists. The same function would work on other kinds of iterables that we haven't seen yet.
To do something a bit more useful, let's sum the squares of a list of numbers, a common computation in statistics.
-
def sum_squares(numbers): """Given a list of numbers, returns the sum of their squares.""" total = 0 for number in numbers: total += number ** 2 return total print sum_squares([5, 3, 8])
total
to be zero.
Then, for each list element in turn, we'll call the element number
and add its square to total
. Finally, we return the
computed total.
Thus, this function works by repeatedly changing total
to
be more and more of the eventual result. We often call this
“accumulating” the result, and total
is an
accumulator variable.
This also illustrates another way of introducing local variables.
The variable number
is local to the loop —
the name doesn't mean anything outside the loop.
Similarly, the variables numbers
and total
are local to the function. Again, this allows us to choose variable
names without worrying about what names are used in other code.
Similarly, we could instead build a new list of the squares of the original list values.
-
def square_list(numbers): """Given a list of numbers, returns a list of the numbers squared.""" squares = [] for number in numbers: squares.append(number ** 2) return squares print square_list([5, 3, 8])
Again, we are accumulating the desired value, which this time is a list.
What happens in the two previous examples if we omit the initialization?
In sum_squares()
, comment out the line total = 0
,
and then use the function. In square_list()
, do the same
with squares = []
.
Exercises
Follow these ideas to define functions that accomplish the following:
-
Returns the product of a list of numbers
def product(numbers): """Given a list of numbers, returns the product of the numbers.""" prod = 1 for number in numbers: prod *= number return prod print product([5, 3, 8])
-
Returns the concatenation of a list of strings.
def concatenate_all(strings): """Given a list of strings, returns the concatenation of the strings.""" result = "" for string in strings: result = result + string return result print concatenate_all(["This ", "is ", "great!"])
As an aside, what single built-in operation will do the same thing as this loop?
"".join(["This ", "is ", "great!"])
We will be practicing with loops all week.