Now that we've examined some basic built-in types, let's look at two important control flow structures which depend on conversions to the bool
type: if
-statements and while
-loops.
Conditional statements allow us to branch execution based on the value of an expression. The form of the statement is the if
keyword, followed by an expression, terminated by a colon to introduce a new block. Let's try this at the REPL:
>>> if True:
Remembering to indent four spaces within the block, we add some code to be executed if the condition is True
, followed by a blank line to terminate the block:
... print("It's true!") ... It's true!
At this point the block will execute, because self-evidently the condition is True. Conversely, if the condition is False
, the code in the block does not execute:
>>> if False: ... print("It's true!") ... >>>
The expression used with the if
-statement will be converted to a bool
just as if the bool()
constructor had been used, so:
>>> if bool("eggs"): ... print("Yes please!") ... Yes please!
If the value is exactly equivalent to something, we then use the if
command as follows:
>>> if "eggs": ... print("Yes please!") ... Yes please!
Thanks to this useful shorthand, explicit conversion to bool
using the bool
constructor is rarely used in Python.
The if
-statement supports an optional else
clause which goes in a block introduced by the else
keyword (followed by a colon) which is indented to the same level as the if
keyword. Let's start by creating (but not finishing) an if
-block:
>>> h = 42 >>> if h > 50: ... print("Greater than 50")
To start the else
block in this case, we just omit the indentation after the three dots:
... else: ... print("50 or smaller") ... 50 or smaller
For multiple conditions you might be tempted to do something like this:
>>> if h > 50: ... print("Greater than 50") ... else: ... if h < 20: ... print("Less than 20") ... else: ... print("Between 20 and 50") ... Between 20 and 50
Whenever you find yourself with an else
-block containing a nested if
statement, like this, you should consider using Python's elif
keyword which is a combined else-if
.
As the Zen of Python reminds us, Flat is better than nested:
>>> if h > 50: ... print("Greater than 50") ... elif h < 20: ... print("Less than 20") ... else: ... print("Between 20 and 50") ... Between 20 and 50
This version is altogether easier to read.
Python has two types of loop: for
-loops and while
-loops. We've already briefly encountered for
-loops back when we introduced significant whitespace, and we'll return to them soon, but right now we'll cover while
-loops.
The While
-loops in Python are introduced by the while keyword, which is followed by a boolean expression. As with the condition for if
-statements, the expression is implicitly converted to a boolean value as if it has been passed to the bool()
constructor. The while
statement is terminated by a colon because it introduces a new block.
Let's write a loop at the REPL which counts down from five to one. We'll initialize a counter variable called c
to five, and keep looping until we reach zero. Another new language feature here is the use of an augmented-assignment operator, -=
, to subtract one from the value of the counter on each iteration. Similar augmented assignment operators exist for the other basic math operations such as addition and multiplication:
>>> c = 5 >>> while c != 0: ... print(c) ... c -= 1 ... 5 4 3 2 1
Because the condition — or predicate — will be implicitly converted to bool
, just as if a call to the bool()
constructor were present, we could replace the above code with the following version:
>>> c = 5 >>> while c: ... print(c) ... c -= 1 ... 5 4 3 2 1
This works because the conversion of the integer value of c
to bool
results in True
until we get to zero which converts to False
. That said, to use this short form in this case might be described as un-Pythonic, because, referring back to the Zen of Python, explicit is better than implicit. We place higher value of the readability of the first form over the concision of the second form.
The While
-loops are often used in Python where an infinite loop is required. We achieve this simply by passing True
as the predicate expression to the while construct:
>>> while True: ... print("Looping!") ... Looping! Looping! Looping! Looping! Looping! Looping! Looping! Looping!
Now you're probably wondering how we get out of this loop and regain control of our REPL! Simply press Ctrl+C:
Looping! Looping! Looping! Looping! Looping! Looping!^C Traceback (most recent call last): File "<stdin>", line 2, in <module> KeyboardInterrupt >>>
Python intercepts the key stroke and raises a special exception which terminates the loop. We'll be talking much more about what exceptions are, and how to use them, later in Chapter 6, Exceptions.
Many programming languages support a loop construct which places the predicate test at the end of the loop rather than at the beginning. For example, C, C++, C# and Java support the do-while
construct. Other languages have repeat-until loops instead or as well. This is not the case in Python, where the idiom is to use while True
together with an early exit, facilitated by the break statement.
The break
statement jumps out of the loop — and only the innermost loop if severals loops have been nested — continuing execution immediately after the loop body.
Let's look at an example of break
, introducing a few other Python features along the way, and examine it line-by-line:
>>> while True: ... response = input() ... if int(response) % 7 == 0: ... break ...
We start with a while True
: for an infinite loop. On the first statement of the while block we use the built-in input()
function to request a string from the user. We assign that string to a variable called response.
We now use an if
-statement to test whether the value provided is divisible by seven. We convert the response string to an integer using the int()
constructor and then use the modulus operator, %, to divide by seven and give the remainder. If the remainder is equal to zero, the response was divisible by seven, and we enter the body of the if
-block.
Within the if
-block, now two levels of indentation deep, we start with eight spaces and use the break keyword. break terminates the inner-most loop — in this case the while
-loop — and causes execution to jump to the first statement after the loop.
Here, that statement is the end of the program. We enter a blank line at the three dots prompt to close both the if
-block and the while
-block. Our loop will start executing, and will pause at the call to input()
waiting for us to enter a number. Let's try a few:
12 67 34 28 >>>
As soon as we enter a number divisible by seven the predicate becomes True, we enter the if
-block, and then we literally break
out of the loop to the end of program, returning us to the REPL prompt.