Control structures
This chapter shows operators used in conditional expressions, followed by control structures.
Comparison operators
These operators yield True
or False
boolean values as a result of comparison between two values.
>>> 0 != '0'
True
>>> 0 == int('0')
True
>>> 'hi' == 'Hi'
False
>>> 4 > 3.14
True
>>> 4 >= 4
True
>>> 'bat' < 'at'
False
>>> 2 <= 3
True
Python is a strictly typed language. So, unlike context-based languages like Perl, you have to explicitly use type conversion when needed. As an exercise, try using any of the <
or <=
or >
or >=
operators between numeric and string values.
See docs.python: Comparisons and docs.python: Operator precedence for documentation and other details.
Truthy and Falsy values
The values by themselves have Truthy and Falsy meanings when used in a conditional context. You can use the bool() built-in function to explicitly convert them to boolean values.
The numerical value zero, an empty string and None
are Falsy. Non-zero numbers and non-empty strings are Truthy. See docs.python: Truth Value Testing for a complete list.
>>> type(True)
<class 'bool'>
>>> type(False)
<class 'bool'>
>>> bool(4)
True
>>> bool(0)
False
>>> bool(-1)
True
>>> bool('')
False
>>> bool('hi')
True
>>> bool(None)
False
Boolean operators
You can use the and
and or
boolean operators to combine comparisons. The not
operator is useful to invert a condition.
>>> 4 > 3.14 and 2 <= 3
True
>>> 'hi' == 'Hi' or 0 != '0'
True
>>> not 'bat' < 'at'
True
>>> num = 0
>>> not num
True
The and
and or
operators are also known as short-circuit operators. These will evaluate the second expression if and only if the first one evaluates to True
and False
respectively. Also, these operators return the result of the expressions used, which can be a non-boolean value. The not
operator always returns a boolean value.
>>> num = 5
# here, num ** 2 will NOT be evaluated
>>> num < 3 and num ** 2
False
# here, num ** 2 will be evaluated as the first expression is True
>>> num < 10 and num ** 2
25
# not operator always gives a boolean value
>>> not (num < 10 and num ** 2)
False
>>> 0 or 3
3
>>> 1 or 3
1
Comparison chaining
Similar to mathematical notations, you can chain comparison operators. Apart from resulting in a terser conditional expression, this also has the advantage of having to evaluate the middle expression only once.
>>> num = 5
# using boolean operator
>>> num > 3 and num <= 5
True
# comparison chaining
>>> 3 < num <= 5
True
>>> 4 < num > 3
True
>>> 'bat' < 'cat' < 'cater'
True
Membership operator
The in
comparison operator checks if a given value is part of a collection of values. Here's an example with the range()
function:
>>> num = 5
# range() will be discussed in detail later in this chapter
# this checks if num is present among the integers 3 or 4 or 5
>>> num in range(3, 6)
True
>>> 6 in range(3, 6)
False
You can build your own collection of values using various data types like list
, set
, tuple
etc. These data types will be discussed in detail in later chapters.
>>> num = 21
>>> num == 10 or num == 21 or num == 33
True
# RHS value here is a tuple data type
>>> num in (10, 21, 33)
True
>>> 'cat' not in ('bat', 'mat', 'pat', 'Cat')
True
When applied to strings, the in
operator performs substring comparison.
>>> fruit = 'mango'
>>> 'an' in fruit
True
>>> 'at' in fruit
False
if-elif-else
Similar to the function definition, control structures require indenting its body of code. And, there's a :
character after you specify the conditional expression. You should be already familiar with if
and else
keywords from other programming languages. Alternate conditional branches are specified using the elif
keyword. You can nest these structures and each branch can have one or more statements.
Here's an example of an if-else
structure within a user defined function. Note the use of indentation to separate different structures. Examples with the elif
keyword will be seen later.
# odd_even.py
def isodd(n):
if n % 2:
return True
else:
return False
print(f'{isodd(42) = }')
print(f'{isodd(-21) = }')
print(f'{isodd(123) = }')
Here's the output of the above program.
$ python3.13 odd_even.py
isodd(42) = False
isodd(-21) = True
isodd(123) = True
As an exercise, reduce the isodd()
function body to a single statement instead of four. This is possible with features already discussed in this chapter — the ternary operator discussed in the next section would be an overkill.
Python doesn't support the
switch
control structure. See stackoverflow: switch statement in Python? for workarounds. docs.python: match statement is a powerful alternative toswitch
, introduced in the Python 3.10 version.
Ternary operator
Python doesn't support the traditional ?:
ternary operator syntax. Instead, it uses if-else
keywords in the same line as illustrated below.
def absolute(num):
if num >= 0:
return num
else:
return -num
The above if-else
structure can be rewritten using the ternary operator as shown below:
def absolute(num):
return num if num >= 0 else -num
Or, just use the abs() built-in function, which has support for complex numbers, fractions, etc. Unlike the above program, abs()
will also handle -0.0
correctly.
See stackoverflow: ternary conditional operator for other ways to emulate the ternary operation in Python.
True
andFalse
boolean values are equivalent to1
and0
in integer context. So, for example, the above ternary expression can also be written as(-num, num)[num >= 0]
.
for loop
Counter based loop can be constructed using the range() built-in function and the in
operator. The range()
function can be called in the following ways:
range(stop)
range(start, stop)
range(start, stop, step)
Both ascending and descending order arithmetic progressions can be constructed using these variations. When skipped, the default values are start=0
and step=1
. For understanding purposes, a C
-like code snippet is shown below:
# ascending order
for(i = start; i < stop; i += step)
# descending order
for(i = start; i > stop; i += step)
Here's a sample multiplication table:
>>> num = 9
>>> for i in range(1, 5):
... print(f'{num} * {i} = {num * i}')
...
9 * 1 = 9
9 * 2 = 18
9 * 3 = 27
9 * 4 = 36
The range
, list
, tuple
, str
data types (and some more) fall under sequence types. There are multiple operations that are common to these types (see docs.python: Common Sequence Operations for details). For example, you could iterate over these types using the for
loop. The start:stop:step
slicing operation is another commonality among these types. You can test your understanding of the slicing syntax by converting a range()
expression to list
or tuple
types.
>>> list(range(5))
[0, 1, 2, 3, 4]
>>> list(range(2, 11, 2))
[2, 4, 6, 8, 10]
>>> list(range(120, 99, -4))
[120, 116, 112, 108, 104, 100]
As an exercise, create this arithmetic progression -2, 1, 4, 7, 10, 13
using the range()
function. Also, see what value you get during each iteration of for c in 'hello'
.
while loop
Use while
loop when you want to execute statements as long as the condition evaluates to True
. Here's an example:
# countdown.py
count = int(input('Enter a positive integer: '))
while count > 0:
print(count)
count -= 1
print('Go!')
Here's a sample run of the above script:
$ python3.13 countdown.py
Enter a positive integer: 3
3
2
1
Go!
As an exercise, rewrite the above program using a for
loop. Can you think of a scenario where you must use a while
loop instead of for
?
Python doesn't support
++
or--
operations. As shown in the above program, combining arithmetic operations with assignment is supported.
break and continue
The break
statement is useful to quit the current loop immediately. Here's an example where you can keep getting the square root of a number until you enter an empty string. Recall that an empty string is Falsy.
>>> while True:
... num = input('enter a number: ')
... if not num:
... break
... print(f'square root of {num} is {float(num) ** 0.5:.4f}')
...
enter a number: 2
square root of 2 is 1.4142
enter a number: 3.14
square root of 3.14 is 1.7720
enter a number:
>>>
When continue
is used, further statements are skipped and the next iteration of the loop is started, if any. For example, in file processing you often need to skip certain lines like headers, comments, etc.
>>> for num in range(10):
... if num % 3:
... continue
... print(f'{num} * 2 = {num * 2}')
...
0 * 2 = 0
3 * 2 = 6
6 * 2 = 12
9 * 2 = 18
As an exercise, use appropriate range()
logic so that the if
statement is no longer needed.
See docs.python: break, continue, else for more details and the curious case of
else
clause in loops.
Assignment expression
Quoting from docs.python: Assignment expressions:
An assignment expression (sometimes also called a "named expression" or "walrus") assigns an expression to an identifier, while also returning the value of the expression.
The while
loop snippet from the previous section can be re-written using the assignment expression as shown below:
>>> while num := input('enter a number: '):
... print(f'square root of {num} is {float(num) ** 0.5:.4f}')
...
enter a number: 2
square root of 2 is 1.4142
enter a number: 3.14
square root of 3.14 is 1.7720
enter a number:
>>>
See Assignment Expressions (PEP 572) and my book on regular expressions for more details and examples.
Exercises
- If you don't already know about FizzBuzz, check out the problem statement on rosettacode and implement it in Python. See also Why Can't Programmers.. Program?
- Print all numbers from
1
to1000
(inclusive) which reads the same in reversed form in both the binary and decimal formats. For example,33
in decimal is100001
in binary and both of these are palindromic. You can either implement your own logic or search online for palindrome testing in Python. - Write a function that returns the maximum nested depth of curly braces for a given string input. For example,
'{{a+2}*{{b+{c*d}}+e*d}}'
should give4
. Unbalanced or wrongly ordered braces like'{a}*b{'
and'}a+b{'
should return-1
.
If you'd like more exercises to test your understanding, check out these excellent resources:
- Exercism, Hackinscience and Practicepython — beginner friendly
- PythonExercises — my interactive TUI app
- Adventofcode, Codewars, Python Morsels — for intermediate to advanced level users
- Checkio, Codingame — gaming based challenges
- /r/dailyprogrammer — interesting challenges
See also Python Programming Exercises, Gently Explained — a free ebook that includes gentle explanations of the problem, the prerequisite coding concepts you'll need to understand the solution, etc.