Looping
Contents
22. Looping#
Author: Tue Nguyen
22.1. Outline#
Overview
for
loopswhile
loopsControl loops with
next
andcontinue
Infinite loops
Comprehensions
22.2. Overview#
We often write programs to automate repetitive tasks
The benefits are
We write a small chunk of code but can repeat it as many times as we want
If we want to change something to the code logic, we only have to make modifications in one place
This reduces the workload and makes it less prone to errors
This repetition is called looping
In Python, we can do looping using
for
orwhile
22.3. for
loops#
22.3.1. Basic for
loops#
You are already familiar with the basic use of the
for
loopIn this section, we will learn about it in more detail through more interesting examples
The template for the
for
loop is as follows
for item in iterable:
# Do something
a) Ex 1: say hello
Say hello to a list of people
# Init a list of people
people = ["John", "Bob", "Mary"]
# Write code to say hello to as many people as we want
for p in people:
print(f"Hello {p}")
Hello John
Hello Bob
Hello Mary
b) Ex 2: looping with enumerate
When iterating through a sequence, you might want to access both the value and the index of an element
You can do this with
enumerate()
In each iteration,
enumerate()
returns a tuple of 2 entriesThe first one is the index (counting from
0
)The second one is the current element of the sequence
# Init a list of players with higher-ranked ones first
players = ["Bill", "Peter", "Tony"]
# Print players with ranking
for i, p in enumerate(players):
print(f"{p} is ranked {i + 1}")
Bill is ranked 1
Peter is ranked 2
Tony is ranked 3
c) Ex 3: compute a cumulative sum
Compute the sum of elements from a list of numbers
# Init a list of numbers
numbers = [1, 2, -2.5, 30, 4, 7]
# Compute the sum of elements in numbers
total = 0
for n in numbers:
total += n
# Print the result
total
41.5
# We can double check out result using sum() function
sum(numbers)
41.5
d) Ex 4: see what happens in each iteration
In Ex 3, we only see the final result
However, we can write a program to see what happens under the hood by moving the
print
statement inside the loop
# Init
numbers = [1, 2, -2.5, 30, 4, 7]
total = 0
# Loop and print the state of total at each iteration
for n in numbers:
total += n;
print(total)
1
3
0.5
30.5
34.5
41.5
e) Ex 5: compute factorial
Compute the factorial for a positive integer
Recall that the factorial of a positive number \(n\) is \(n! = 1\times 2\times \dots \times n\)
If \(n = 0\) then \(n! = 1\)
For simplicity, in this example, we write code for
n > 0
only
# Init a number n
n = 6
# Init a variable to for the factorial with value 1
fact = 1
# Loop through a range of ints from 1 to n
# In each iteration, MULTIPLY the current element with fact
for i in range(1, n + 1):
fact *= i
# Check the result
fact
720
f) Ex 6: count the number of characters of each type
Given a sentence in English, count the number of consonants, vowels, and non-cased (non-letter) characters
# Init a string
s = "Hi. How are you?"
# Snippet 1: use nested if
# Init three counter variables
n_consonants = 0
n_vowels = 0
n_non_letters = 0
# Iterate through the lowercase version of s
# and update the counters accordingly
for c in s.lower():
if c.isalpha():
if c in "ueoai":
n_vowels += 1
else:
n_consonants += 1
else:
n_non_letters += 1
# Print results
print(f"{n_vowels} vowels")
print(f"{n_consonants} consonants")
print(f"{n_non_letters} non-letter characters")
6 vowels
5 consonants
5 non-letter characters
# Snippet 2: use if elif to avoid nested if
# Init three counter variables
n_consonants = 0
n_vowels = 0
n_non_letters = 0
# Iterate through the lowercase version of s
# and update the counters accordingly
for c in s.lower():
if not c.isalpha():
n_non_letters += 1
elif c in "ueoai":
n_vowels += 1
else:
n_consonants += 1
# Print results
print(f"{n_vowels} vowels")
print(f"{n_consonants} consonants")
print(f"{n_non_letters} non-letter characters")
6 vowels
5 consonants
5 non-letter characters
g) Ex 7: extract numbers of each types
From a list of numbers, extract positive, negative, and zero elements into three lists
# Init a list of numbers
x = [1, 2, -1.5, 0, 7, 9.5, -10, 0, 3.4, -5.5]
# Init 3 variables to hold extracted elements
pos = []
neg = []
zeros = []
# Extract elements
for e in x:
if e > 0:
pos.append(e)
elif e < 0:
neg.append(e)
else:
zeros.append(e)
# Print the result
print(f"Positive numbers: {pos}")
print(f"Negative numbers: {neg}")
print(f"Zeros numbers: {zeros}")
Positive numbers: [1, 2, 7, 9.5, 3.4]
Negative numbers: [-1.5, -10, -5.5]
Zeros numbers: [0, 0]
22.3.2. Nested for
loops#
We can write a
for
loop inside anotherfor
loopThis is called a nested
for
loopHowever, be careful that computation can explode very quickly if your program involves nested
for
loopsEx: if the outer loop has \(1,000\) iterations and the inner loop has \(2,000\) iterations, then your program has to perform \(2,000,000\) iterations in total
a) Ex 1: compute factorial for each integer in a list
Loop through a list of positive integers, and at each iteration, print the factorial of that integer
# Init a list of positive integers
numbers = [1, 3, 4, 6, 7]
for n in numbers:
fact = 1
for i in range(1, n + 1):
fact *= i
print(f"{n}! = {fact}")
1! = 1
3! = 6
4! = 24
6! = 720
7! = 5040
b) Ex 2: print a triangle
Print out the following triangle
0 1 2 3 4 5 6 7 8 9
1 2 3 4 5 6 7 8 9
2 3 4 5 6 7 8 9
3 4 5 6 7 8 9
4 5 6 7 8 9
5 6 7 8 9
6 7 8 9
7 8 9
8 9
9
for i in range(10):
for j in range(i, 10):
print(j, end=" ")
print("")
0 1 2 3 4 5 6 7 8 9
1 2 3 4 5 6 7 8 9
2 3 4 5 6 7 8 9
3 4 5 6 7 8 9
4 5 6 7 8 9
5 6 7 8 9
6 7 8 9
7 8 9
8 9
9
22.4. while
loops#
22.4.1. Basic while
loops#
Another way to repeat a block of code in Python is to use a
while
loopThe template is as follows
while condition:
# Do something
Here is how a
while
loop worksFirst, Python evaluates
condition
If
False
, Python skip the code insidewhile
and proceed to the next statement afterwhile
If
True
, Python executes the code insidewhile
, and after that Python goes back to checkcondition
As long as
condition
is stillTrue
, Python continues repeating the code insidewhile
a) Ex 1: compute the sum of numbers in a list
In an earlier example, we saw how to use a
for
loop to compute the sum of a list of numbersWe can also use a
while
loop to achieve the same thing
# Init a list
x = [1, 2, 10, -5]
x
[1, 2, 10, -5]
# Compute the sum
i = 0
total = 0
while i < len(x):
# Add x[i] to the total
total += x[i]
# Important: increase i
# to move to the next element
i += 1
# Check the result
print(total)
8
What happened?
First, we initiate 2 variables
i
: to track the iterationstotal
: to accumlate the sum of elements ofx
In the first iteration
At the beginning,
i = 0
andtotal = 0
Condition
i < len(x)
is true becauselen(x)
is4
Thus, Python executes the code inside
while
The statement
total += x[i]
addx[0]
tototal
, and nowtotal
is1
The statement
i += 1
increase by1
and nowi
is1
There’s no more statements so Python moves to the next iteration
In the second iteration
At the beginning,
i = 1
andtotal = 1
Python checks the condition
i < len(x)
and sees that it is still trueThus, Python executes the code inside
while
and at the endtotal
is updated to3
andi
is updated to2
This process continues until the 4th iteration is done
After the 4th iteration,
i = 4
andtotal = 8
Python checks the condition
is < len(x)
as usual and it gets aFalse
(because4 < 4
is false)Since the condition is false, the loop terminates
Important: people often forget to increase the counter (
i += 1
) and this leads to an infinite loop (because the condition is always true)
b) Ex 2: redo Ex 1 with .pop()
# Init a list
x = [1, 2, 10, -5]
# Compute the sum
total = 0
while x:
total += x.pop()
# Check the result
total
8
What happened?
First, we initiate a list with 4 elements
In the first iteration of the
while
loopPython converts
x
tobool
and gets aTrue
(because the list is non-empty)Since the condition is true, Python executes the statement inside
while
The last element of
x
(which is-5
) is popped out and added tototal
x
now has 3 elements
In the second iteration
Python repeats checking the condition and still gets a
True
(becausex
is still non-empty)And the last element of
x
(which is10
now) is added tototal
x
now has 2 elements
The above process is repeated until
x
becomes an empty listWhen Python checks the condition, this empty list is converted to
False
The loop ends
22.4.2. Nested while loops#
Similar to
for
, we can also nest anotherwhile
orfor
loop inside awhile loop
Just be aware that the computation can explode with nested loops
22.5. Control loops with break
and continue
#
The
break
keyword terminates the entire loop and moves the execution to the statement after the loopThe
continue
keyword just skips the current iteration and moves the execution to the next iteration (if any)
22.5.1. break
#
Ex: print elements of a list of and stop until encountering the first negative number
# Init a list
x = [1, 2, 0, -3, 7, 4, -5, 8]
x
[1, 2, 0, -3, 7, 4, -5, 8]
# Case 1: also print out the first negative numbers
for e in x:
print(e)
if e < 0:
break
1
2
0
-3
Explanation
In the above code, Python iterates through each element of
x
from left to rightIn each iteration, Python prints out the element and then checks if the element is negative
We can see that in the 4th iteration, this checking condition is true (because
-3 < 0
)Thus, the loop ends after 4 iterations
# Case 2: do not print out the first negative numbers
# All we need to do is to do the checking first
# If we encounter the first negative number, the loop ends immediately
# and this negative number will never be printed out
for e in x:
if e < 0:
break
print(e)
1
2
0
22.5.2. continue
#
Ex: print out positive numbers only
# Init a list
x = [1, 2, 0, -3, 7, 4, -5, 8]
x
[1, 2, 0, -3, 7, 4, -5, 8]
# Print out only positive numbers
for e in x:
if e <= 0:
continue
print(e)
1
2
7
4
8
Explanation
In each iteration, Python checks if the current element
e
is non-negative or notIf true (
e
is non-negative), then Python will execute thecontinue
statement which ignores everything after theif
(in this case, theprint
statement) and move to the next iterationIf false (
e
is indeed positive), then Python will execute sequentially and print out the elementThus, unlike
break
,continue
just skips some code but does not terminate the loop
# Of course, we can solve the above example without using continue
for e in x:
if e > 0:
print(e)
1
2
7
4
8
22.6. Infinite loops#
Sometimes we are not sure how many iterations will be needed to accomplish a task
Thus, we use a
while
loop withTrue
as the conditionThis loop will repeat potentially forever
To avoid that, we put an
if
statement inside the loop to break it when some condition is met
Ex: guess a number
Suppose you have to randomly choose an integer from 0 to 5
My secrete number is 3
If the number you choose coincide with my secrete number, the program ends
Otherwise, you repeat the choosing again until your number and mine are the same
As you might see, this loop potentially repeats forever
# First we need to import random module
# We might also need to set a seed for reproducibility
# (you can safely ignore this for now)
import random
random.seed(1)
# Init
secrete_num = 3
# Guess
while True:
guess = random.randint(0, 5)
print(f"Your guess: {guess}")
if guess == secrete_num:
print("You guessed correctly")
break
Your guess: 1
Your guess: 4
Your guess: 0
Your guess: 2
Your guess: 0
Your guess: 3
You guessed correctly
22.7. Comprehensions#
Comprehension is a quick way to create an iterable without using a loop
Let’s consider the following example: “generate a list of squares of positive integers less than 10”
# Method 1: use a for loop
squares = []
for i in range(9):
squares.append(i*i)
squares
[0, 1, 4, 9, 16, 25, 36, 49, 64]
# Method 2: use list comp
squares = [i*i for i in range(9)]
squares
[0, 1, 4, 9, 16, 25, 36, 49, 64]
22.7.1. List comprehensions#
Create a list without using a loop
Syntax:
[expr for item in iterable if condition]
The
if
part is optional
a) Ex 1: extract grade >= 5
from a list of grades
# Init a list of grades
grades = [1, 3, 2.5, 7, 8, 5, 6.5, 0, 10, 9.5, 2]
# Extract passing grade
passing_grades = [g for g in grades if g >= 5]
# Check the result
passing_grades
[7, 8, 5, 6.5, 10, 9.5]
b) Ex 2: extract customers with names starting with "A"
# Init a list of customers
customers = ["Anna", "Bob", "Jack", "Alexander", "tom", "andrew"]
# Extract customers whose names start with "A" (case-insensitive)
customers_a = [c for c in customers if c.lower().startswith("a")]
# Check the result
customers_a
['Anna', 'Alexander', 'andrew']
c) Ex 3: create a list of absolute paths from a list of file names
# Init
file_names = ["data.csv", "report.docx", "slides.ppt", "analysis.ipynb"]
dir_path = "D:/projects/proj_1/"
# Create absolute paths
abs_paths = [dir_path + f for f in file_names]
# Check the result
abs_paths
['D:/projects/proj_1/data.csv',
'D:/projects/proj_1/report.docx',
'D:/projects/proj_1/slides.ppt',
'D:/projects/proj_1/analysis.ipynb']
22.7.2. Tuple comprehensions#
Similar to list comp, however, the output is a generator instead of a tuple (for optimization purposes)
Syntax:
(expr for item in iterable if condition)
The
if
part is also optionalTo see the actual elements of the result, we can convert it to a tuple using
tuple()
No need for examples
22.7.3. Dict comprehensions#
Dic comp is a quick way to create a dict without using a loop
Syntax:
(expr_key: expr_value for item in iterable if condition)
The
if
part is also optional
a) Ex 1: create a dict of lowercase: uppercase
Suppose we have a sentence with words separated by spaces
Create a dict with words in lowercase as keys and words in uppercase as values
# Init a sentence
s = "I want to learn Python"
# Create the dict
d = {w.lower(): w.upper() for w in s.split()}
# Check the result
d
{'i': 'I', 'want': 'WANT', 'to': 'TO', 'learn': 'LEARN', 'python': 'PYTHON'}
b) Ex 2: extract high-income individuals
Suppose we have a dict of people with IDs as keys and incomes as values
Extract those with
income >= 100,000
# Init a dict
people = {"ID01": 50e3, "ID02": 72e3, "ID03": 105e3, "ID04": 35e3, "ID05": 125e3}
# Extract high-income individuals
high_income = {k: v for k, v in people.items() if v >= 100e3}
# Check the result
high_income
{'ID03': 105000.0, 'ID05': 125000.0}
c) Ex 3: create a dict of letters with their counts
Suppose we have a string
Create a dict with each letter as a key and its number of occurrences as values
# Init a string
s = "Hello"
# Create the dict
d = {k: s.count(k) for k in set(s)}
# Check the result
d
{'e': 1, 'H': 1, 'l': 2, 'o': 1}
d) Ex 4: create a dict by zipping lists
Suppose we have a list of drinks and another list of prices for the drinks
Create a dict with drinks as keys and prices as values
# Init drinks and prices
drinks = ["Cappuccino", "Americano", "Espresso", "Macchiato"]
prices = [1.5, 1.2, 1.6, 2.]
# Create a dict with drinks as keys and prices as values
d = {d: p for d, p in zip(drinks, prices)}
# Check the result
d
{'Cappuccino': 1.5, 'Americano': 1.2, 'Espresso': 1.6, 'Macchiato': 2.0}
22.8. Summary#
Overview
Looping is repeating a block of code multiple times for the purpose of automating repetitive tasks
Benefits
Write once, run as many times as we want
If we want to modify something, we have to make changes in one place
This reduces manual work and makes it less prone to errors
In Python, we can do looping using
for
orwhile
for
loops
Syntax
for item in iterable: # Do something
Each element of
iterable
will be visited once from left to rightEach visit is called an iteration
We can access both the elements and the corresponding indices using
enumerate()
A
for
loop can be nested in anotherfor
loop (be aware of computation explosion)
while
loops
Syntax
while condition: # Do something
As long as
condition
is true, the code block insidewhile
is still executed (each execution is an iteration)When
condition
is false, the loop endsThe
while
loop is often used when we are not sure how many iterations are needed (as in the case of an infinite loop)
break
and continue
The
break
keyword terminates the entire loop and moves the execution to the statement after the loopThe
continue
keyword just skips the current iteration and moves the execution to the next iteration (if any)For
break
, it is possible that the loop does not iterate over all elements of the iterable. However, forcontinue
, every element of the iterable is visited
Infinite loops
We use an infinite loop (
while True:
) when we are not sure how many iterations will be needed to accomplish a taskRemember to put an
if
statement inside the loop to check for the exit condition
Comprehensions
Comprehension is a quick way to create an iterable without using a loops
We have
List comprehensions
Tuple comprehensions
Dict comprehensions
Note that comprehensions are not meant to replace loops