Skip to article frontmatterSkip to article content
Site not loading correctly?

This may be due to an incorrect BASE_URL configuration. See the MyST Documentation for reference.

Loops (while and for)

Loops with the keyword while

i = 0
while i < 4:
    i += 1
print("i =", i)
i = 4
i = 0
while i < 4:
    i += 1
    print("i =", i)
i = 1
i = 2
i = 3
i = 4
Solution to Exercise 1
numbers = [67, 12, 2, 9, 23, 5]

avg0 = sum(numbers) / len(numbers)

tmp = 0
i = 0
while i < len(numbers):
    tmp += numbers[i]
    i = i + 1
avg1 = tmp / len(numbers)

assert avg0 == avg1

Simulating do while stop_condition construction

while True:
    if stop_condition:
        break
    # content of the do-while loop

Loops with the keyword for

values = range(5)
for i in values:
    print("i =", i)
i = 0
i = 1
i = 2
i = 3
i = 4

The build-in function range() is very useful for loops. It creates a range object, which is an iterable, immutable sequence of numbers.

# syntax is range(start, stop, step)
range(0, 4, 1)
range(0, 4)

(default start is 0, default step is 1)

range(4)
range(0, 4)
list(range(1, 8, 2))
[1, 3, 5, 7]

range() is memory efficient because it does not store all the numbers in memory.

range(1_000_000_000_000_000)
range(0, 1000000000000000)

It is common to use range() directly in for loops:

for idx in range(4):
    print(idx, end=", ")
0, 1, 2, 3, 

for loops are of course not limited to integers:

groceries = ["Carrots", "Cabbage", "Milk", "Onions", "Pepper"]

print("Groceries list")
for grocery in groceries:
    print("-", grocery)
Groceries list
- Carrots
- Cabbage
- Milk
- Onions
- Pepper

The built-in function enumerate is very useful to access indices

print("My top 5 groceries:")
for index, grocery in enumerate(groceries):
    print(f"{index}. {grocery}")
My top 5 groceries:
0. Carrots
1. Cabbage
2. Milk
3. Onions
4. Pepper

Loops: keywords continue and break

for x in range(1, 8):
    if x == 5:
        continue
    print(x, end=", ")
1, 2, 3, 4, 6, 7, 
for x in range(1, 8):
    if x == 5:
        break
    print(x, end=", ")
1, 2, 3, 4, 
Solution to Exercise 2
l = [67, 12, 2, 9, 23, 5]
# simple implementation with sum and len
avg0 = sum(l) / len(l)

# now with for and without sum
avg2 = 0
for elem in l:
    avg2 += elem
avg2 /= len(l)

# now with for and enumerate, but without sum and len
avg3 = 0
for i, elem in enumerate(l):
    avg3 += elem
avg3 /= i + 1

# and now let's check:
assert avg2 == avg0
Solution to Exercise 3
# we can change ordering, let's sort
print(numbers)
l_sorted = sorted(numbers)
print(l_sorted)
missing = None
for idx, elem in enumerate(l_sorted):
    if elem != idx:
        missing = idx
        break
if missing is None:
    missing = len(numbers)

print(f"{missing = }")
assert missing == i_removed
[1, 11, 12, 5, 9, 10, 18, 15, 14, 13, 19, 3, 7, 8, 4, 2, 0, 16, 6]
[0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 18, 19]
missing = 17
# we cannot sort -> higher complexity
for elem in range(len(numbers) + 1):
    if elem not in numbers:
        break
missing = elem

print(f"{missing = }")
assert missing == i_removed
missing = 17
# another solution
actual_sum = sum(numbers)
len_numbers = len(numbers)
original_sum = (len_numbers + 1) * (len_numbers) // 2
missing = original_sum - actual_sum

print(f"{missing = }")
assert missing == i_removed
missing = 17
# yet another solution:
availables = [0] * size
for number in numbers:
    availables[number] = 1

# now the removed element is the index of the only 0 element
missing = availables.index(0)
assert missing == i_removed

list: list comprehension

They are iterable so they are often used to make loops. We have already seen how to use the keyword for. For example to build a new list (side note: x**2 computes x^2):

l0 = [1, 4, 10]
l1 = []
for number in l0:
    l1.append(number**2)

print(l1)
[1, 16, 100]

There is a more readable (and slightly more efficient) method to do such things, the list comprehension:

l1 = [number**2 for number in l0]
print(l1)
[1, 16, 100]
# list comprehension with a condition
[s for s in ["a", "bbb", "e"] if len(s) == 1]
['a', 'e']
# lists comprehensions can be cascaded
[(x, y) for x in [1, 2] for y in ["a", "b"]]
[(1, 'a'), (1, 'b'), (2, 'a'), (2, 'b')]
Solution to Exercise 4
text = "basically"


def extract_patterns(text, n=3):
    pat = [text[i : i + n] for i in range(len(text) - n + 1)]
    return pat


print("patterns=", extract_patterns(text))
print("patterns=", extract_patterns(text, n=5))
patterns= ['bas', 'asi', 'sic', 'ica', 'cal', 'all', 'lly']
patterns= ['basic', 'asica', 'sical', 'icall', 'cally']