Control Flow#

By default, statements in a Python script are executed sequentially from top to bottom. If the processing logic requires, the sequential flow of execution can be altered in two ways:

  • Conditional execution: a block of one or more statements will be executed if a certain expression is true

  • Repetitive execution: a block of one or more statements will be repetitively executed as long as a certain expression is true

Conditional Execution#

Conditional execution can help us execute or skip a block of code based on a given condition, thus altering the sequential flow of execution.

If condition#

In Python and other programming languages the keyword if is often used to check if a given condition is true and to execute a certain block of code accordingly.

a = -1

if a > 0:
    print('A is a positive number')

If Else#

If Else allows us to run different blocks of code if the condition defined is true or false.

NOTE: Be careful of the indentation that comes after the colon (:) in the next line. This indentation is necessary and cannot be ignored while writing code.

a = -1
if a > 0:
    print('A is a positive number')
else:
    print('A is a negative number')
A is a negative number

If Elif Else#

Sometimes we might have to make a decision based on multiple conditions. This is where the elif statement can help us achieve our goal. The elif clause helps us check for a second condition if the first condition fails to be true.

a = 0
if a > 0:
    print('A is a positive number')
elif a < 0:
    print('A is a negative number')
else:
    print('A is zero')
A is zero

Nested Conditions#

Conditions can be nested within one another.

a = 6

if a > 0:
    if a % 2 == 0:
        print('A is a positive and even integer')
    else:
        print('A is a positive number')
elif a == 0:
    print('A is zero')
else:
    print('A is a negative number')
A is a positive and even integer

Boolean (or Logical) Operators#

Nested statements are generally slower to run and complicate the code a bit. We can use Boolean (or Logical) operators to escape from nested statements. For example, the above code can be un-nested using the boolean operator ‘and’.

a = 2
if a > 0 and a % 2 == 0:
        print('A is an even and positive integer')
elif a > 0 and a % 2 !=  0:
     print('A is a positive integer')
elif a == 0:
    print('A is zero')
else:
    print('A is negative')
A is an even and positive integer

Similarly we can use the ‘or’ or ‘not’ operators to carry out conditional execution.

user = 'James'
access_level = 4
if user == 'admin' or access_level >= 4:
        print('Access granted!')
else:
    print('Access denied!')
Access granted!
user = 'James'
if not user == 'admin':
        print('Access denied!')
else:
    print('Access granted!')
Access denied!

Match statement#

In case we are checking if a given value is equal to a number of different values, we can write it using if and elif statements as follows:

http_status = 500

if http_status == 400:
    print('Bad request')
elif http_status == 404:
    print('Not found')
elif http_status == 418:
    print("I'm a teapot")
else:
    print("Something is wrong with the internet")
Something is wrong with the internet

We can simplify this by using the match statement. The match statement is basically used to compare a given variable to some value and carry out the appropriate code for it.

http_status = 404
match http_status:
    case 400:
        print("Bad request")
    case 404:
        print("Not found")
    case 418:
        print("I'm a teapot")
    case _:
        print("Something is wrong with the internet")
Not found

NOTE: The last block variable name _ acts as a wildcard and never fails to match. If no case matches, none of the codes in the branches are executed.

Repetitive Execution#

Repetitive execution can help us repeat a certain block of code multiple times, altering the sequential flow of execution. Python provides loops that can help us repeatedly execute a given block of code. There are two types of loops in Python: while loops and for loops.

While Loop#

The while loop is used to execute a block of statements repeatedly until a given condition is satisfied. When the condition becomes false, the lines of code after the loop will be continued to be executed.

count = 0
while count < 6:
    print(count)
    count = count + 1
0
1
2
3
4
5

In the code block above, we have a variable “count” initialized to 0. The while loop checks if the count variables is less than 5. If it is, then the code block below the while loop is executed.
NOTE: Pay attention to the last line, we are increasing the value of the “count” variable everytime the loop runs, thus we are ensuring that at one point the value will be greater than 5 and the loop will stop executing. Never forget this line of code when you are writing loops, else your loops will not stop and run forever.

As with the if condition, we can use “else” in loops as well.

count = 0
while count < 5:
    print(count)
    count += 1 # same as count = count + 1
else:
    print("Goal reached")
0
1
2
3
4
Goal reached

NOTE: In the code above, we have used the short hand for incrementing a variable in Python, count = count + 1 is the same as count += 1

For Loop#

The for loop is used for iterating over a sequence (that is either a list, tuple, dictionary, set , or string).

numbers = [0, 1, 2, 3, 4, 5, 6]
for number in numbers:
    print(number)
0
1
2
3
4
5
6

In the above case, the variable “number” is a temporary variable that is valid only inside the code in the loop.

We can similarly iterate over other sequence objects.

language = 'python'
for letter in language:
    print(letter)
p
y
t
h
o
n
for i in range(len(language)):
    print(language[i])
p
y
t
h
o
n

Detour 1: Range

The above snippet shows two ways of using for loops. The first method is straight forward when iterating over a sequence. In the second method, we are first creating another list using the range method. The range method creates an iterable object from a given number to another given number. Then we are using those numbers as indices to access value in the sequence object (string in this case).

# Range method
a = range(10)
print(a)
range(0, 10)
for i in a:
    print(i)
0
1
2
3
4
5
6
7
8
9

We can use the range method to create a sequence. It takes three inputs (but you can get away with using just one or two) if you want to be more specific with the sequence you want.

range(start, stop, step)

The start value determines the start of the sequence. If it is not provided, the sequence starts at 0.
The stop value detemines the end of the sequence (Note: The final value is not included in the sequence). This value must be provided always.
The step parameter determines the difference between successive numbers in the sequence. The default value is 1.

a = range(2, 15, 2)
for i in a:
    print(i)
2
4
6
8
10
12
14

Detour 2: Enumerate

We can also use another method called enumerate to get index-value pairs from sequence objects. It is fairly straight forward to use.

list1 = ['eat', 'pray', 'love']
enumerate(list1)
<enumerate at 0x1a6545e2480>
for index, item in enumerate(list1):
    print(index, item)
0 eat
1 pray
2 love

Detour ends

We can use for loops to iterate over items in a dictionary. We can get the keys, or key-value pairs at the same time.

person = {
    'first_name':'Asabeneh',
    'last_name':'Yetayeh',
    'age':250,
    'country':'Finland',
    'is_marred':True,
    'skills':['JavaScript', 'React', 'Node', 'MongoDB', 'Python'],
    'address':{
        'street':'Space street',
        'zipcode':'02210'
    }
}
for key in person:
    print(key)
first_name
last_name
age
country
is_marred
skills
address
for key, value in person.items():
    print(key, value) # this way we get both keys and values printed out
first_name Asabeneh
last_name Yetayeh
age 250
country Finland
is_marred True
skills ['JavaScript', 'React', 'Node', 'MongoDB', 'Python']
address {'street': 'Space street', 'zipcode': '02210'}

Earlier, I had mentioned that we cannot get individual elements from sets using their indices. We can however iterate over all the items in a set using the for statement!

it_companies = {'Facebook', 'Google', 'Microsoft', 'Apple', 'IBM', 'Oracle', 'Amazon'}
for company in it_companies:
    print(company)
Microsoft
IBM
Facebook
Google
Apple
Oracle
Amazon

We still cannot access an item in a set by using indices.

for i in range(len(it_companies)):
    print(it_companies[i])
---------------------------------------------------------------------------
TypeError                                 Traceback (most recent call last)
Cell In[24], line 2
      1 for i in range(len(it_companies)):
----> 2     print(it_companies[i])

TypeError: 'set' object is not subscriptable

Tuples have a special quality when it comes to for loops. If you are iterating through a sequence that contains tuples, the item can actually be the tuple itself, this is an example of tuple unpacking. During the for loop we will be unpacking the tuple inside of a sequence and we can access the individual items inside that tuple!

list2 = [(2,4),(6,8),(10,12)]
for tup in list2: # iterating over the list
    print(tup)
(2, 4)
(6, 8)
(10, 12)
# Now with unpacking!
for (t1,t2) in list2:
    print(t2)
4
8
12

As with if statements and while loops, we can use else in for loops

for number in range(11):
    print(number)   # prints 0 to 10, not including 11
else:
    print('The loop stops at', number)
0
1
2
3
4
5
6
7
8
9
10
The loop stops at 10

Break, Continue, and Pass#

for and while loops have special keywords that can be used to modify the execution of the loop.
The break statement halts execution of a loop totally.
The continue statement is used to skip the current iteration, and the loop continues to the next.
The pass statement does nothing. It is generally used when a statement is required syntactically, but there is no action that we want to take.

# execution halted at third step
count = 0
while count < 5:
    print(count)
    count = count + 1
    if count == 3:
        break
0
1
2
# execution halted at 3
numbers = (0,1,2,3,4,5)
for number in numbers:
    print(number)
    if number == 3:
        break
0
1
2
3
# skipping 3
count = 0
while count < 5:
    if count == 3:
        count = count + 1
        continue
    print(count)
    count = count + 1
0
1
2
4
# skipping 3
numbers = (0,1,2,3,4,5)
for number in numbers:
    if number == 3:
        continue
    print(number)
0
1
2
4
5
for i in range(10):
    pass # do nothing

Nested Loops#

As with if conditions, we can make nested loops, i.e., loops inside loops.

person = {
    'first_name': 'Asabeneh',
    'last_name': 'Yetayeh',
    'age': 250,
    'country': 'Finland',
    'is_marred': True,
    'skills': ['JavaScript', 'React', 'Node', 'MongoDB', 'Python'],
    'address': {
        'street': 'Space street',
        'zipcode': '02210'
    }
}
for key in person:
    if key == 'skills':
        for skill in person['skills']:
            print(skill)
JavaScript
React
Node
MongoDB
Python

Reference:#

  1. https://docs.python.org/3/tutorial/controlflow.html

  2. https://www.educative.io/answers/what-are-control-flow-statements-in-python

  3. https://pynative.com/python-control-flow-statements/

  4. https://www.geeksforgeeks.org/enumerate-in-python/