pythonlearn. chapter 5. Extract[69-78]
pythonlearn. chapter 5. Extract[69-78]
Iteration
x = x + 1
This means “get the current value of x, add 1, and then update x with the new
value.”
If you try to update a variable that doesn’t exist, you get an error, because Python
evaluates the right side before it assigns a value to x:
>>> x = x + 1
NameError: name 'x' is not defined
Before you can update a variable, you have to initialize it, usually with a simple
assignment:
>>> x = 0
>>> x = x + 1
57
58 CHAPTER 5. ITERATION
n = 5
while n > 0:
print(n)
n = n - 1
print('Blastoff!')
You can almost read the while statement as if it were English. It means, “While
n is greater than 0, display the value of n and then reduce the value of n by 1.
When you get to 0, exit the while statement and display the word Blastoff!”
More formally, here is the flow of execution for a while statement:
This type of flow is called a loop because the third step loops back around to the
top. We call each time we execute the body of the loop an iteration. For the above
loop, we would say, “It had five iterations”, which means that the body of the loop
was executed five times.
The body of the loop should change the value of one or more variables so that
eventually the condition becomes false and the loop terminates. We call the vari-
able that changes each time the loop executes and controls when the loop finishes
the iteration variable. If there is no iteration variable, the loop will repeat forever,
resulting in an infinite loop.
n = 10
while True:
print(n, end=' ')
n = n - 1
print('Done!')
5.4. FINISHING ITERATIONS WITH CONTINUE 59
If you make the mistake and run this code, you will learn quickly how to stop
a runaway Python process on your system or find where the power-off button is
on your computer. This program will run forever or until your battery runs out
because the logical expression at the top of the loop is always true by virtue of the
fact that the expression is the constant value True.
While this is a dysfunctional infinite loop, we can still use this pattern to build
useful loops as long as we carefully add code to the body of the loop to explicitly
exit the loop using break when we have reached the exit condition.
For example, suppose you want to take input from the user until they type done.
You could write:
while True:
line = input('> ')
if line == 'done':
break
print(line)
print('Done!')
# Code: https://www.py4e.com/code3/copytildone1.py
The loop condition is True, which is always true, so the loop runs repeatedly until
it hits the break statement.
Each time through, it prompts the user with an angle bracket. If the user types
done, the break statement exits the loop. Otherwise the program echoes whatever
the user types and goes back to the top of the loop. Here’s a sample run:
This way of writing while loops is common because you can check the condition
anywhere in the loop (not just at the top) and you can express the stop condition
affirmatively (“stop when this happens”) rather than negatively (“keep going until
that happens.”).
while True:
line = input('> ')
if line[0] == '#':
continue
if line == 'done':
break
print(line)
print('Done!')
# Code: https://www.py4e.com/code3/copytildone2.py
All the lines are printed except the one that starts with the hash sign because
when the continue is executed, it ends the current iteration and jumps back to
the while statement to start the next iteration, thus skipping the print statement.
Sometimes we want to loop through a set of things such as a list of words, the lines
in a file, or a list of numbers. When we have a list of things to loop through, we
can construct a definite loop using a for statement. We call the while statement
an indefinite loop because it simply loops until some condition becomes False,
whereas the for loop is looping through a known set of items so it runs through
as many iterations as there are items in the set.
The syntax of a for loop is similar to the while loop in that there is a for
statement and a loop body:
In Python terms, the variable friends is a list1 of three strings and the for loop
goes through the list and executes the body once for each of the three strings in
the list resulting in this output:
1We will examine lists in more detail in a later chapter.
5.6. LOOP PATTERNS 61
Translating this for loop to English is not as direct as the while, but if you think
of friends as a set, it goes like this: “Run the statements in the body of the for
loop once for each friend in the set named friends.”
Looking at the for loop, for and in are reserved Python keywords, and friend
and friends are variables.
In particular, friend is the iteration variable for the for loop. The variable friend
changes for each iteration of the loop and controls when the for loop completes.
The iteration variable steps successively through the three strings stored in the
friends variable.
• Performing some computation on each item in the loop body, possibly chang-
ing the variables in the body of the loop
We will use a list of numbers to demonstrate the concepts and construction of these
loop patterns.
For example, to count the number of items in a list, we would write the following
for loop:
count = 0
for itervar in [3, 41, 12, 9, 74, 15]:
count = count + 1
print('Count: ', count)
62 CHAPTER 5. ITERATION
We set the variable count to zero before the loop starts, then we write a for loop
to run through the list of numbers. Our iteration variable is named itervar and
while we do not use itervar in the loop, it does control the loop and cause the
loop body to be executed once for each of the values in the list.
In the body of the loop, we add 1 to the current value of count for each of the
values in the list. While the loop is executing, the value of count is the number
of values we have seen “so far”.
Once the loop completes, the value of count is the total number of items. The
total number “falls in our lap” at the end of the loop. We construct the loop so
that we have what we want when the loop finishes.
Another similar loop that computes the total of a set of numbers is as follows:
total = 0
for itervar in [3, 41, 12, 9, 74, 15]:
total = total + itervar
print('Total: ', total)
In this loop we do use the iteration variable. Instead of simply adding one to the
count as in the previous loop, we add the actual number (3, 41, 12, etc.) to the
running total during each loop iteration. If you think about the variable total, it
contains the “running total of the values so far”. So before the loop starts total is
zero because we have not yet seen any values, during the loop total is the running
total, and at the end of the loop total is the overall total of all the values in the
list.
As the loop executes, total accumulates the sum of the elements; a variable used
this way is sometimes called an accumulator.
Neither the counting loop nor the summing loop are particularly useful in practice
because there are built-in functions len() and sum() that compute the number of
items in a list and the total of the items in the list respectively.
To find the largest value in a list or sequence, we construct the following loop:
largest = None
print('Before:', largest)
for itervar in [3, 41, 12, 9, 74, 15]:
if largest is None or itervar > largest :
largest = itervar
print('Loop:', itervar, largest)
print('Largest:', largest)
Before: None
Loop: 3 3
5.6. LOOP PATTERNS 63
Loop: 41 41
Loop: 12 41
Loop: 9 41
Loop: 74 74
Loop: 15 74
Largest: 74
The variable largest is best thought of as the “largest value we have seen so far”.
Before the loop, we set largest to the constant None. None is a special constant
value which we can store in a variable to mark the variable as “empty”.
Before the loop starts, the largest value we have seen so far is None since we have
not yet seen any values. While the loop is executing, if largest is None then we
take the first value we see as the largest so far. You can see in the first iteration
when the value of itervar is 3, since largest is None, we immediately set largest
to be 3.
After the first iteration, largest is no longer None, so the second part of the
compound logical expression that checks itervar > largest triggers only when
we see a value that is larger than the “largest so far”. When we see a new “even
larger” value we take that new value for largest. You can see in the program
output that largest progresses from 3 to 41 to 74.
At the end of the loop, we have scanned all of the values and the variable largest
now does contain the largest value in the list.
To compute the smallest number, the code is very similar with one small change:
smallest = None
print('Before:', smallest)
for itervar in [3, 41, 12, 9, 74, 15]:
if smallest is None or itervar < smallest:
smallest = itervar
print('Loop:', itervar, smallest)
print('Smallest:', smallest)
Again, smallest is the “smallest so far” before, during, and after the loop executes.
When the loop has completed, smallest contains the minimum value in the list.
Again as in counting and summing, the built-in functions max() and min() make
writing these exact loops unnecessary.
The following is a simple version of the Python built-in min() function:
def min(values):
smallest = None
for value in values:
if smallest is None or value < smallest:
smallest = value
return smallest
In the function version of the smallest code, we removed all of the print statements
so as to be equivalent to the min function which is already built in to Python.
64 CHAPTER 5. ITERATION
5.7 Debugging
As you start writing bigger programs, you might find yourself spending more time
debugging. More code means more chances to make an error and more places for
bugs to hide.
One way to cut your debugging time is “debugging by bisection.” For example, if
there are 100 lines in your program and you check them one at a time, it would
take 100 steps.
Instead, try to break the problem in half. Look at the middle of the program,
or near it, for an intermediate value you can check. Add a print statement (or
something else that has a verifiable effect) and run the program.
If the mid-point check is incorrect, the problem must be in the first half of the
program. If it is correct, the problem is in the second half.
Every time you perform a check like this, you halve the number of lines you have
to search. After six steps (which is much less than 100), you would be down to
one or two lines of code, at least in theory.
In practice it is not always clear what the “middle of the program” is and not
always possible to check it. It doesn’t make sense to count lines and find the exact
midpoint. Instead, think about places in the program where there might be errors
and places where it is easy to put a check. Then choose a spot where you think
the chances are about the same that the bug is before or after the check.
5.8 Glossary
5.9 Exercises
Exercise 1: Write a program which repeatedly reads integers until the user enters
“done”. Once “done” is entered, print out the total, count, and average of the
integers. If the user enters anything other than a integers, detect their mistake
using try and except and print an error message and skip to the next integers.
5.9. EXERCISES 65
Enter a number: 4
Enter a number: 5
Enter a number: bad data
Invalid input
Enter a number: 7
Enter a number: done
16 3 5.333333333333333
Exercise 2: Write another program that prompts for a list of numbers as above
and at the end prints out both the maximum and minimum of the numbers instead
of the average.
66 CHAPTER 5. ITERATION