Loops¶
Loops are a powerful building block for writing programs. They make it possible to write programs that perform repeated work without having to make copies of the same instructions (lines of code). Loops also make programs easier to read and maintain. They enable us to decide how many times to iterate while a program is running (for instance, based on a calculation or something the user enters), rather than at the time we wrote the program. In fact, it would be impossible to write most programs without loops.
Basics
The most basic loop in Python is the for-each loop:
for <var> in <expression>:
<body>
The expression must yield a value, such as a list or a string, that
can be iterated over. We will explain this construct using lists to
start. For each iteration through the loop, the variable (<var>
) takes on
a value from the list starting at index 0 and proceeding in order.
Here is an example loop:
In [1]: l1 = [1, "abc", 5.7, [1, 3, 5]]
In [2]: for y in l1:
...: print("y = " + str(y))
...:
y = 1
y = abc
y = 5.7
y = [1, 27.0, 5]
y = 27
Please note that ...:
is the prompt that ipython3 uses when a
piece of code is spread over multiple lines. It is not part of the
syntax of the for loop.
Combining loops and append
It is very common to use loops to create new list from an existing
list. For example, here is code that generates a new list (nl
) in
which the ith element of the new list is the square of the ith element
of a list l
.
In [3]: l = [1, 2, 3, 4, 5]
In [4]: nl = []
In [5]: for x in l:
...: nl.append(x*x)
...:
In [6]: nl
Out[6]: [1, 4, 9, 16, 25]
The variable nl
initially refers to an empty list. Every time
around the loop a new entry is added to the list.
Range
At times it is useful to iterate over the index space of a
list of length N (0, 1, …, N-1) rather than iterating over the
contents of the list. The range
function is useful for this
purpose. In earlier versions of Python, the range
function
produced a list. In Python 3, range
yields an iterator that
produces a sequence of integers as needed. It can be used in three
ways:
range(ub)
which yields an iterator that produces a sequence of consecutive integer values from 0 up to, but not including, the upper boundub
range(lb, ub)
which yields an iterator that produces a sequence of consecutive integer values starting at the lower boundlb
up to, but not incuding, the upper boundub
.range(lb, ub, incr)
which yields an iterator that produces a sequence of integer values starting at the lower boundlb
up to, but not incuding, the upper boundub
, in increments of sizeincr
.
Iterating over the index space of a loop
An alternate way of iterating over a list is by iterating over the index
space of a list l
using the expression range(len(l))
.
For example, we could rewrite the example above as:
In [7]: for i in range(len(l1)):
...: y = l1[i]
...: print("y = " + str(y))
...:
y = 1
y = abc
y = 5.7
y = [1, 27.0, 5]
y = 27
This style of iterating over lists is common in other languages, but less common in Python, where iterating as described in basics is more common.
Enumerate
Occasionally, it is useful to use both an element of a list and its
index in a loop. The expression enumerate(l)
yields an iterator
that produces a sequence of tuples, each with an index and the value
from the list at that index. For example,
In [8]: for (i, val) in enumerate(l1):
...: print("l1[" + str(i) + "] = " + str(val))
...:
l1[0] = 1
l1[1] = abc
l1[2] = 5.7
l1[3] = [1, 3, 5]