A program’s
control
flow
is the order
in which the program’s code executes. The control
flow of a Python program is regulated by conditional statements,
loops, and function calls. This section covers the
if
statement and for
and
while
loops; functions are covered later in this
chapter. Raising and handling exceptions also affects control flow;
exceptions are covered in Chapter 6.
Often, you need to execute some
statements only if some condition holds, or choose statements to
execute depending on several mutually exclusive conditions. The
Python compound statement if
, which uses
if
, elif
, and
else
clauses, lets you conditionally execute
blocks of statements. Here’s the syntax for the
if
statement:
ifexpression
:statement(s)
elifexpression
:statement(s)
elifexpression
:statement(s)
... else:statement(s)
The
elif
and else
clauses are
optional. Note that unlike some languages, Python does not have a
switch
statement, so you must use
if
, elif
, and
else
for all conditional processing.
Here’s a typical if
statement:
if x < 0: print "x is negative" elif x % 2: print "x is positive and odd" else: print "x is even and non-negative"
When there are multiple statements in a clause (i.e., the clause controls a block of statements), the statements are placed on separate logical lines after the line containing the clause’s keyword (known as the header line of the clause) and indented rightward from the header line. The block terminates when the indentation returns to that of the clause header (or further left from there). When there is just a single simple statement, as here, it can follow the : on the same logical line as the header, but it can also be placed on a separate logical line, immediately after the header line and indented rightward from it. Many Python practitioners consider the separate-line style more readable:
if x < 0: print "x is negative" elif x % 2: print "x is positive and odd" else: print "x is even and non-negative"
You can use any Python expression as
the condition in an if
or elif
clause. When you use an expression this way, you are using it in a
Boolean
context
. In a
Boolean context, any value is taken as either true or false. As we
discussed earlier, any non-zero number or non-empty string, tuple,
list, or dictionary evaluates as true. Zero (of any numeric type),
None
, and empty strings, tuples, lists, and
dictionaries evaluate as false. When you want to test a value
x
in a Boolean context, use the following
coding style:
if x
:
This is the clearest and most Pythonic form. Don’t use:
ifx
is True: ifx
= = True: if bool(x
):
There is a crucial difference between saying that an expression
“returns True
"
(meaning the expression returns the value 1
intended as a Boolean result) and saying that an expression
“evaluates as true” (meaning the
expression returns any result that is true in a Boolean context).
When testing an expression, you care about the latter condition, not
the former.
If the expression for the if
clause evaluates as
true, the statements following the if
clause
execute, and the entire if
statement ends.
Otherwise, the expressions for any elif
clauses
are evaluated in order. The statements following the first
elif
clause whose condition is true, if any, are
executed, and the entire if
statement ends.
Otherwise, if an else
clause exists, the
statements following it are executed.
The while
statement in Python supports repeated execution of a statement or
block of statements that is controlled by a conditional expression.
Here’s the syntax for the while
statement:
whileexpression
:statement(s)
A while
statement can also include an
else
clause and break
and
continue
statements, as we’ll
discuss shortly.
Here’s a typical while
statement:
count = 0 while x > 0: x = x // 2 # truncating division count += 1 print "The approximate log2 is", count
First, expression
, which is known as the
loop
condition
, is
evaluated. If the condition is false, the while
statement ends. If the loop condition is satisfied, the statement or
statements that comprise the loop
body
are executed. When the loop body finishes
executing, the loop condition is evaluated again, to see if another
iteration should be performed. This process continues until the loop
condition is false, at which point the while
statement ends.
The loop body should contain code that eventually makes the loop
condition false, or the loop will never end unless an exception is
raised or the loop body executes a break
statement. A loop that is in a function’s body also
ends if a return
statement executes in the loop
body, as the whole function ends in this case.
The for
statement
in Python supports repeated execution of a statement or block of
statements that is controlled by an iterable expression.
Here’s the syntax for the for
statement:
fortarget
initerable
:statement(s)
Note that the in
keyword is part of the syntax of
the for
statement and is functionally unrelated to
the in
operator used for membership testing. A
for
statement can also include an
else
clause and break
and
continue
statements, as we’ll
discuss shortly.
Here’s a typical for
statement:
for letter in "ciao": print "give me a", letter, "..."
iterable
may be any Python expression
suitable as an argument to built-in function iter
,
which returns an iterator object (explained in detail in the next
section). target
is normally an identifier
that names the control
variable
of the loop; the for
statement successively rebinds this variable to each item of the
iterator, in order. The statement or statements that comprise the
loop
body
execute once for
each item in iterable
(unless the loop
ends because an exception is raised or a break
or
return
statement is
executed).
A target with multiple identifiers is also allowed, as with an
unpacking assignment. In this case, the iterator’s
items must then be sequences, each with the same length, equal to the
number of identifiers in the target. For example, when
d
is a dictionary, this is a typical way
to loop on the items in d
:
for key, value in d.items( ): if not key or not value: del d[key] # keep only true keys and values
The items
method returns a list of key/value
pairs, so we can use a for
loop with two
identifiers in the target to unpack each item into
key
and value
.
If the iterator has a mutable underlying object, that object must not
be altered while a for
loop is in progress on it.
For example, the previous example cannot use
iteritems
instead of items
.
iteritems
returns an iterator whose underlying
object is d
, so therefore the loop body cannot
mutate d
(by del
d[key]
). items
returns a list,
though, so d
is not the underlying object of the
iterator and the loop body can mutate d
.
The control variable may be rebound in the loop body, but is rebound
again to the next item in the iterator at the next iteration of the
loop. The loop body does not execute at all if the iterator yields no
items. In this case, the control variable is not bound or rebound in
any way by the for
statement. If the iterator
yields at least one item, however, when the loop statement
terminates, the control variable remains bound to the last value to
which the loop statement has bound it. The following code is thus
correct, as long as someseq
is not empty:
for x in someseq: process(x) print "Last item processed was", x
An
iterator
is any object
i
such that you can call
i
.next( )
without any
arguments. i
.next( )
returns the next item of iterator i
, or,
when iterator i
has no more items, raises
a StopIteration
exception. When you write a class
(see Chapter 5), you can allow instances of the
class to be iterators by defining such a method
next
. Most iterators are built by implicit or
explicit calls to built-in function iter
, covered
in Chapter 8. Calling a generator also returns an
iterator, as we’ll discuss later in this
chapter.
The for
statement implicitly calls
iter
to get an iterator. The following statement:
for x in c:
statement(s)
is equivalent to:
_temporary_iterator = iter(c)
while True:
try: x = _temporary_iterator.next( )
except StopIteration: break
statement(s)
Thus, if
iter(
c
)
returns an iterator i
such that
i
.next( )
never raises
StopIteration
(an infinite
iterator
), the loop for
x
in
c
: never terminates
(unless the statements in the loop body contain suitable
break
or return
statements or
propagate exceptions).
iter(
c
)
,
in turn, calls special method c
.__iter__( )
to obtain and return an iterator on
c
. We’ll talk more about
the special method __iter__
in Chapter 5.
Iterators were first introduced in Python 2.2. In earlier versions,
for
x
in
S
: required
S
to be a sequence that was indexable with
progressively larger indices 0
,
1
, ..., and raised an
IndexError
when indexed with a too-large index.
Thanks to iterators, the for
statement can now be
used on a container that is not a sequence, such as a dictionary, as
long as the container is iterable (i.e., it defines an __iter__
special method so that function
iter
can accept the container as the argument and
return an iterator on the container). Built-in functions that used to
require a sequence argument now also accept any iterable.
Looping over a sequence of integers
is a common task, so Python provides built-in functions
range
and xrange
to generate
and return integer sequences. The simplest, most idiomatic way to
loop n times in Python
is:
for i in xrange(n
):statement(s)
range(
x
)
returns a list whose items are consecutive integers from
0
(included) up to x
(excluded).
range(
x
,y
)
returns a list whose items are consecutive integers from
x
(included) up to
y
(excluded). The result is the empty list
if x
is greater than or equal to
y
.
range(
x
,y
,step
)
returns a list of integers from x
(included) up to y
(excluded), such that
the difference between each two adjacent items in the list is
step
. If step
is less than 0
, range
counts
down from x
to
y
. range
returns the
empty list when x
is greater than or equal
to y
and step is greater than
0
, or when x
is less
than or equal to y
and
step
is less than 0
. If
step
equals 0
,
range
raises an exception.
While range
returns a normal list object, usable
for all purposes, xrange
returns a special-purpose
object, specifically intended to be used in iterations like the
for
statement shown previously.
xrange
consumes less memory than
range
for this specific use. Leaving aside memory
consumption, you can use range
wherever you could
use xrange
.
A
common use of a for
loop is to inspect each item
in a sequence and build a new list by appending the results of an
expression computed on some or all of the items inspected. The
expression form, called a list
comprehension
, lets you code this common idiom
concisely and directly. Since a list comprehension is an expression
(rather than a block of statements), you can use it directly wherever
you need an expression (e.g., as an actual argument in a function
call, in a return
statement, or as a subexpression
for some other expression).
A list comprehension has the following syntax:
[expression
fortarget
initerable
lc-clauses
]
target
and
iterable
are the same as in a regular
for
statement. You must enclose the
expression
in parentheses if it indicates
a tuple.
lc-clauses
is a series of zero or more
clauses, each with one of the following forms:
fortarget
initerable
ifexpression
target
and
iterable
in each for
clause of a list comprehension have the same syntax as those in a
regular for
statement, and the
expression
in each if
clause of a list comprehension has the same syntax as the
expression
in a regular
if
statement.
A list comprehension is equivalent to a for
loop
that builds the same list by repeated calls to the resulting
list’s append
method. For example
(assigning the list comprehension result to a variable for clarity):
result1 = [x+1 for x in some_sequence]
is the same as the for
loop:
result2 = [ ] for x in some_sequence: result2.append(x+1)
Here’s a list comprehension that uses an
if
clause:
result3 = [x+1 for x in some_sequence if x>23]
which is the same as a for
loop that contains an
if
statement:
result4 = [ ] for x in some_sequence: if x>23: result4.append(x+1)
And here’s a list comprehension that uses a
for
clause:
result5 = [x+y for x in alist for y in another]
which is the same as a for
loop with another
for
loop nested inside:
result6 = [ ] for x in alist: for y in another: result6.append(x+y)
As these examples show, the order of for
and
if
in a list comprehension is the same as in the
equivalent loop, but in the list comprehension the nesting stays
implicit.
The break
statement is allowed only inside a loop body. When
break
executes, the loop terminates. If a loop is
nested inside other loops, break
terminates only
the innermost nested loop. In practical use, a
break
statement is usually inside some clause of
an if
statement in the loop body so that it
executes conditionally.
One common use of break
is in the implementation
of a loop that decides if it should keep looping only in the middle
of each loop iteration:
while True: # this loop can never terminate naturally x = get_next( ) y = preprocess(x) if not keep_looping(x, y): break process(x, y)
The continue
statement is allowed only inside a loop body. When
continue
executes, the current iteration of the
loop body terminates, and execution continues with the next iteration
of the loop. In practical use, a continue
statement is usually inside some clause of an if
statement in the loop body so that it executes conditionally.
The
continue
statement can be used in place of deeply
nested if
statements within a loop. For example:
for x in some_container: if not seems_ok(x): continue lowbound, highbound = bounds_to_test( ) if x<lowbound or x>=highbound: continue if final_check(x): do_processing(x)
This equivalent code does conditional processing without
continue
:
for x in some_container: if seems_ok(x): lowbound, highbound = bounds_to_test( ) if lowbound<=x<highbound: if final_check(x): do_processing(x)
Both versions function identically, so which one you use is a matter of personal preference.
Both
the while
and for
statements
may optionally have a trailing else
clause. The
statement or statements after the else
execute
when the loop terminates naturally (at the end of the
for
iterator or when the while
loop condition becomes false), but not when the loop terminates
prematurely (via break
, return
,
or an exception). When a loop contains one or more
break
statements, you often need to check whether
the loop terminates naturally or prematurely. You can use an
else
clause on the loop for this purpose:
for x in some_container: if is_ok(x): break # item x is satisfactory, terminate loop else: print "Warning: no satisfactory item was found in container" x = None
The body of a Python compound
statement cannot be empty—it must contain at least one
statement. The pass
statement, which performs no
action, can be used as a placeholder when a statement is
syntactically required but you have nothing specific to do.
Here’s an example of using pass
in a conditional statement as a part of somewhat convoluted logic,
with mutually exclusive conditions being tested:
if condition1(x): process1(x) elif x>23 or condition2(x) and x<5: pass # nothing to be done in this case elif condition3(x): process3(x) else: process_default(x)
Python supports exception handling
with the try
statement, which includes
try
, except
,
finally
, and else
clauses. A
program can explicitly raise an exception with the
raise
statement. As we’ll discuss
in detail in Chapter 6, when an exception is
raised, normal control flow of the program stops and Python looks for
a suitable exception handler.
Get Python in a Nutshell now with the O’Reilly learning platform.
O’Reilly members experience books, live events, courses curated by job role, and more from O’Reilly and nearly 200 top publishers.