Conditionals and Iterating#

Conditions with if, elif and else#

Often it is necessary to make decisions in a program based on whether some criteria is True or False. For this we can use comparison operators such as > (greater than), > (less than) and == (mean numerically identical). For example:

x = 7
if x > 7:
    print('Gotcha!')

We can also handle the case where the main condition was not satisified using the keyword else:

x = 2
if x > 7:
    print('Gotcha!')
else:
    print('Not Gotcha!')
Not Gotcha!

Multiple cases can also be handled using the keyword elif, meaning means “else if”:

x = -2
if x > 0:
    print('Positive')
elif x < 0:
    print('Negative')
else:
    print('Must be zero')
Negative
s = "Hello"
if 'e' in s:
    print('Found an e')
elif 'l' in s:
    print('Found an l')
elif 't' in s:
    print('Found an t')
else:
    print('Cannot find any of my preferred letters e, l and t')
Found an e

And one can use multiple and more complicated boolean expressions in if ... elif ... conditional blocks. You can use logical expressions involving and and or and parentheses to group them.

day_of_the_week = 'Tuesday'
color_of_the_car = 'Red'
slept_well = True
month = 'December'
#location = 'Chicago'
location = 'Mumbai'

if month == 'December' and location == 'Chicago':
    print('Hibernate!')
elif (day_of_the_week == 'Tuesday' or day_of_the_week == 'Thursday') and slept_well:
    print('Run 5km today')
elif day_of_the_week == 'Friday' and color_of_the_car == 'Red':
    print('Little Red Corvette - escaping for the weekend!')
elif day_of_the_week in ['Monday', 'Wednesday']:
    print('Normal days, normal things...')
else:
    print('It must be Sunday or I slept badly or my car broke down')
Run 5km today

Indentation in Python#

An important feature of python is the use of indentation to indicate which execution elements are part of (for example) an if ... elif ... construct. For example consider the following examples:

x = 9
if (x>0):
    print('Gotcha')
else:
    print('Nope')
print('Completed')
Gotcha
Completed
x = 9
if (x>0):
    print('Gotcha')
else:
    print('Nope')
    print('Completed')
Gotcha

Note that the indentation (number of spaces) must be consistent throughout any program you write. (Commonly 4 spaces is used.) Python will generate an error if the indentation is not consistent.

Iterating over things with for#

Often in programming we want to do something for a large number of cases. A for loop is a (sequential) method to iterate over each of those cases, one after another. In the following we use the range(5) function, which will sequentially values in the order [0,1,2,3,4]. For each iteration of the loop, the variable i is set to the next value and the indented code is executed.

for i in range(5):
    print(i)
0
1
2
3
4

The function range(start,stop,step) offers more flexibility and we use it here to construct a list of integers l.

l = []
for i in range(0,20,2):
    l.append(i)
print(l)
[0, 2, 4, 6, 8, 10, 12, 14, 16, 18]

More complex things can be executed within the loop:

l = []
for i in range(0,20,2):
    if (i%3==2):
        l.append(i*5)
print(l)
[10, 40, 70]

We are not limited to looping on numeric values and in fact we can loop over elements of other data types such as lists. For each iteration of the loop we define a variable flavor which will be taken sequentially from the list of flavors.

flavors = ['vanilla','mango','pistachio','strawberry','chocolate']
for flavor in flavors:
    print(f'Flavor of the day is {flavor}')
Flavor of the day is vanilla
Flavor of the day is mango
Flavor of the day is pistachio
Flavor of the day is strawberry
Flavor of the day is chocolate

Continue executing while some condition is true#

In some cases one wants to execute repetitively a piece of code until some condition is true (where the code executed is affecting something relevant for the evaluation of the condition). While one can use a for loop when the condition is simple enough that the number of times to execute is known in advance, sometimes it isn’t clear in advance when the condition will become true. An example is when a calculation as part of each iteration (for which the answer is nominally not known in advance). This can be done using a while loop:

# Calculate when the last number < 10000 when tripling each iteration
n = 1
while n < 10000:
    print(n)
    n *= 3
1
3
9
27
81
243
729
2187
6561

Handling Many Matches for a Single Expression with Match ... Case#

If you are just have a single expression (as opposed to multiple and varied boolean expressions) that you want to match against a series of patterns/options using if ... elif ... elif ... elif ... elif ... chain can be complicated. A more readable method is to use a match case statement.

people = { "Alice": "New York", "Bob": "Bangalore", "Charlie": "Paris", "David": "Tokyo",
    "Eve": "New York", "Frank": "Rome", "Grace": "Mumbai", "Heidi": "Paris",
    "Priya": "Mumbai", "Ivan": "New York", "Judy": "Tokyo", "Kevin": "Berlin",
    "Liam": "London", "Mia": "New York", "Noah": "Paris", "Olivia": "Tokyo",
    "Peter": "Berlin", "Quinn": "London", "Rahul": "Mumbai", "Mei": "Shanghai",
    "Sven": "Stockholm", "Arjun": "Paris", "Giuseppe": "Berlin" }
berlin = []
mumbai = []
paris = []
unknown = []
unknown_cities = set()  # Use a set to get unique values
for key,value in people.items():
    match value:
        case 'Berlin':
            berlin.append(key)
        case 'Mumbai':
            mumbai.append(key)
        case 'Paris':
            paris.append(key)
        case _:                     # _ matches any value
            unknown.append(key)
            unknown_cities.add(value)
print(f'Inhabitants of Berlin: {berlin}')
print(f'Inhabitants of Mumbai: {mumbai}')
print(f'Inhabitants of Paris: {paris}')
print(f'Inhabitants of other unknown cities: {unknown}')
print(f'The unknown cities are: {unknown_cities}')
Inhabitants of Berlin: ['Kevin', 'Peter', 'Giuseppe']
Inhabitants of Mumbai: ['Grace', 'Priya', 'Rahul']
Inhabitants of Paris: ['Charlie', 'Heidi', 'Noah', 'Arjun']
Inhabitants of other unknown cities: ['Alice', 'Bob', 'David', 'Eve', 'Frank', 'Ivan', 'Judy', 'Liam', 'Mia', 'Olivia', 'Quinn', 'Mei', 'Sven']
The unknown cities are: {'Shanghai', 'Bangalore', 'Rome', 'Tokyo', 'Stockholm', 'New York', 'London'}

Loops involving lists and dicts#

hindi_numbers = ["ek", "do", "tīn", "chār", "pāñch", "chhah", "sāt", "āṭh"]
for name in hindi_numbers:
    print(name)
ek
do
tīn
chār
pāñch
chhah
sāt
āṭh
for n,name in enumerate(hindi_numbers):
    print(f'{name} is {n+1}')
ek is 1
do is 2
tīn is 3
chār is 4
pāñch is 5
chhah is 6
sāt is 7
āṭh is 8
greek_to_me = {
    'alpha': 1,
    'beta': 2,
    'gamma': 3,
    'delta': 4,
    'epsilon': 5,
    'zeta': 6,
    'eta': 7,
    'theta': 8
}
for key in greek_to_me.keys():
    print(key)
alpha
beta
gamma
delta
epsilon
zeta
eta
theta
for value in greek_to_me.values():
    print(value)
1
2
3
4
5
6
7
8
for key,value in greek_to_me.items():
    print(f'{key} has value {value}')
alpha has value 1
beta has value 2
gamma has value 3
delta has value 4
epsilon has value 5
zeta has value 6
eta has value 7
theta has value 8

List Comprehensions#

Python also offers a concise method for iterating over something that can be helpful in certain circumstances, e.g. when constructing a list:

l = [(x**2 - 10) for x in range(8)]
print(l)
[-10, -9, -6, -1, 6, 15, 26, 39]

This can be combined with an inline conditional:

l = [(x**2 - 10) for x in range(8) if x%2 == 0]  # Choose only even numbers
print(l)
[-10, -6, 6, 26]

Even if called “list” comprehensions, the same syntax can be used to construct other things such as dicts and sets:

d = {x:x**2 for x in range(-10,10)}  # create a dictionary
d
{-10: 100,
 -9: 81,
 -8: 64,
 -7: 49,
 -6: 36,
 -5: 25,
 -4: 16,
 -3: 9,
 -2: 4,
 -1: 1,
 0: 0,
 1: 1,
 2: 4,
 3: 9,
 4: 16,
 5: 25,
 6: 36,
 7: 49,
 8: 64,
 9: 81}
s = {x**2 for x in range(-10,10)}  # Create a set (which will store unique values and not duplicate values)
s
{0, 1, 4, 9, 16, 25, 36, 49, 64, 81, 100}