1.10. Control Structures¶
As we noted earlier, algorithms require two important control structures: iteration and selection. Both of these are supported by Python in various forms. The programmer can choose the statement that is most useful for the given circumstance.
For iteration, Python provides a standard
while statement and a very
for statement. The while statement repeats a body of code
as long as a condition evaluates to
True. For example,
>>> counter = 1 >>> while counter <= 5: ... print("Hello, world") ... counter = counter + 1 Hello, world Hello, world Hello, world Hello, world Hello, world
prints out the phrase
Hello, world five times. The condition on the
while statement is evaluated at the start of each repetition. If the
condition evaluates to
True, the body of the statement will execute. It is
easy to see the structure of a Python
while statement due to the
mandatory indentation pattern that the language enforces.
while statement is a very general-purpose iterative structure
that we will use in a number of different algorithms. In many cases, a
compound condition will control the iteration. A fragment such as
while counter <= 10 and not done: ...
would cause the body of the statement to be executed only in the case
where both parts of the condition are satisfied. The value of the
counter would need to be less than or equal to 10, and the
value of the variable
done would need to be
True) so that
True and True results in
Even though this type of construct is very useful in a wide variety of
situations, another iterative structure, the
for statement, can be
used in conjunction with many of the Python collections. The
statement can be used to iterate over the members of a collection, so
long as the collection is a sequence. So, for example,
>>> for item in [1, 3, 6, 2, 5]: ... print(item) ... 1 3 6 2 5
assigns the variable
item to be each successive value in the list
[1, 3, 6, 2, 5]. The body of the iteration is then executed. This works for
any collection that is a sequence (lists, tuples, and strings).
A common use of the
for statement is to implement definite iteration
over a range of values. The statement
>>> for item in range(5): ... print(item ** 2) ... 0 1 4 9 16 >>>
will perform the
will return a range object representing the sequence 0, 1, 2, 3, 4 and each
value will be assigned to the variable
item. This value is then
squared and printed.
Another useful version of this iteration structure is used to process each character of a string. The following code fragment iterates over a list of strings and for each string processes each character by appending it to a list. The result is a list of all the letters in all of the words.
Selection statements allow programmers to ask questions and then, based
on the result, perform different actions. Most programming languages
provide two versions of this useful construct: the
if...else and the
if. A simple example of a binary selection uses the
>>> import math >>> n = 16 >>> if n < 0: ... print("Sorry, value is negative") ... else: ... print(math.sqrt(n)) ... 4.0 >>>
In this example, the object referred to by
n is checked to see if it
is less than zero. If it is, a message is printed stating that it is
negative. If it is not, the statement performs the
else clause and
computes the square root.
Selection constructs, as with any control construct, can be nested so
that the result of one question helps decide whether to ask the next.
For example, assume that
score is a variable holding a reference to
a score for a computer science test.
>>> if score >= 90: ... print("A") ... else: ... if score >= 80: ... print("B") ... else: ... if score >= 70: ... print("C") ... else: ... if score >= 60: ... print("D") ... else: ... print("F")
This fragment will classify a value called
score by printing the
letter grade earned. If the score is greater than or equal to 90, the
statement will print
A. If it is not (
else), the next question
is asked. If the score is greater than or equal to 80, then it must be
between 80 and 89 since the answer to the first question was false. In
this case print
B is printed. You can see that the Python
indentation pattern helps to make sense of the association between
else without requiring any additional syntactic elements.
An alternative syntax for this type of nested selection uses the
elif keyword. The
else and the next
if are combined so as to
eliminate the need for additional nesting levels. Note that the final
else is still necessary to provide the default case if all other
>>> if score >= 90: ... print("A") ... elif score >= 80: ... print("B") ... elif score >= 70: ... print("C") ... elif score >= 60: ... print("D") ... else: ... print("F") >>>
Python also has a single-way selection construct, the
With this statement, if the condition is true, an action is performed.
In the case where the condition is false, processing simply continues on
to the next statement after the
if. For example, the following
fragment will first check to see if the value of a variable
negative. If it is, then it is modified by the absolute value function.
Regardless, the next action is to compute the square root.
if n < 0: n = abs(n) print(math.sqrt(n))
Test your understanding of what we have covered so far by trying the following exercise. Modify the code from Activecode 8 so that the final list only contains a single copy of each letter.
Returning to lists, there is an alternative method for creating a list
that uses iteration and selection constructs known as a list
comprehension. A list comprehension allows you to easily create a list
based on some processing or selection criteria. For example, if we would
like to create a list of the first 10 perfect squares, we could use a
>>> sq_list =  >>> for x in range(1, 11): ... sq_list.append(x * x) ... >>> sq_list [1, 4, 9, 16, 25, 36, 49, 64, 81, 100] >>>
Using a list comprehension, we can do this in one step as
>>> sq_list=[x * x for x in range(1, 11)] >>> sq_list [1, 4, 9, 16, 25, 36, 49, 64, 81, 100] >>>
x takes on the values 1 through 10 as specified by the
for construct. The value of
x * x is then computed and added to
the list that is being constructed.
The general syntax for a list comprehension also allows a selection criteria to be added so that only certain items get added. For example,
>>> sq_list=[x * x for x in range(1,11) if x % 2 != 0] >>> sq_list [1, 9, 25, 49, 81] >>>
This list comprehension constructs a list that contains the squares of only the odd numbers in the range from 1 to 10. Any sequence that supports iteration can be used within a list comprehension to construct a new list.
>>>[ch.upper() for ch in 'comprehension' if ch not in 'aeiou'] ['C', 'M', 'P', 'R', 'H', 'N', 'S', 'N'] >>>
Test your understanding of list comprehensions by redoing Activecode 1 using list comprehensions. For an extra challenge, see if you can figure out how to remove the duplicates.