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 == avg1Simulating do while stop_condition construction¶
while True:
if stop_condition:
break
# content of the do-while loopLoops 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¶
continue: passes the block in the loop and continues the loop.
for x in range(1, 8):
if x == 5:
continue
print(x, end=", ")1, 2, 3, 4, 6, 7, break: stop the loop.
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 == avg0Solution 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_removedmissing = 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_removedmissing = 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_removedlist: 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']