Chapter 7: for-loops
The for loop
In on of the previous chapter we have defined the word list word_list
:
word_list = ["my", "name", "is", "Gandalf"]
print(word_list)
['my', 'name', 'is', 'Gandalf']
We also learned, that we can access individual entries via indexing:
print(word_list[0])
print(word_list[1])
print(word_list[2])
print(word_list[3])
my
name
is
Gandalf
Instead of printing out each entry by indexing each element manually, we can automatize this task with a so-called for-loop:
for any_index in any_list_of_length_N:
# N-times iteration of your command(s)
# that command can even use the any_index-value
any_list_of_length_N
is any list, over which we’d like to iterateany_index
is an iterator-placeholder, that gets/becomes each value of the list step-by-step with each iteration- the commands followed after the “
:
” will be executed as many times asany_list_of_length_N
has entries
# for-loop example 1:
for current_word in word_list:
print(current_word)
my
name
is
Gandalf
As you can see, current_word
becomes step-by-step the entries of the pre-defined word_list
list-variable.
Code indentation
Python relies on indentation (whitespace at the beginning of a line) to define the scope of code blocks as for for-loops (but also for if-conditions and function definitions). The for-block and any other code block doe not require a specific “end”-indicator, just un-indent after you finished the block.
Exercise 1
- Create a new script and define the number list
number_list = [67, 68, 69, 70]
. - Write a for-loop, that iterates over
number_list
and prints out each element entry-by-entry.
# Your solution here:
current entry: 67
current entry: 68
current entry: 69
current entry: 70
Toggle solution
The range
command
Sometimes you don’t want the iterator to become directly the entries of the iterating list, but an index value. This can be achieved via the range
command paired with the len
command:
# for-loop example 2:
print(f"the length of my list is {len(word_list)}")
for i in range(0, len(word_list), 1):
print(f"at index {i} there is "
f"the entry: {word_list[i]}")
the length of my list is 4
at index 0 there is the entry: my
at index 1 there is the entry: name
at index 2 there is the entry: is
at index 3 there is the entry: Gandalf
The range
command accepts three arguments: range(start, stop, step)
:
- generates an iterator from
start
-value (included) tostop
-value (not included) in the given integerstep
-size. - skipping the
start
-value let’srange
by default start at 0. - skipping the
step
-value let’srange
by default step in step-sizes of 1.
E.g., range(0, 4, 1)
is identical to range(4)
.
The output of range
is nothing that you can print out or use as a variable - it’s a specific iterator-construct for the for-loop. But there is a workaround to get (and validate) the iterator entries generated by range
: list(range(start, stop, step))
. For example:
print(range(10))
range(0, 10)
my_new_list = list(range(10))
print(f"my_new_list: {my_new_list}")
my_new_list: [0, 1, 2, 3, 4, 5, 6, 7, 8, 9]
my_new_list_2 = list(range(3,10,2))
print(f"my_new_list_2: {my_new_list_2}")
my_new_list_2: [3, 5, 7, 9]
my_new_list_3 = list(range(len(word_list)))
print(f"my_new_list_3: {my_new_list_3}")
my_new_list_3: [0, 1, 2, 3]
Exercise 2
- Create a new cell in your script from the previous Exercise 1.
- Create a new number list
number_list_2
that ranges from 3 to 13 in the step-size of 1 (use therange
andlist
command). - Write a for-loop, that iterates over
number_list_2
and prints out each element entry-by-entry and its according index, by using therange
andlen
command. - Modify the step-size to 2 and re-run you script/cell.
# Your solution 2.1-2.2 here:
number_list_2: [3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13]
the length of number_list_2: 11
# Your solution 2.3 here:
0. index has the value 3
1. index has the value 6
2. index has the value 9
3. index has the value 12
# Your solution 2.4 here:
Toggle solution
Example use-case
11, 11
3 + 5 = 8
4 + 6 = 10
5 + 7 = 12
6 + 8 = 14
7 + 9 = 16
8 + 10 = 18
9 + 11 = 20
10 + 12 = 22
11 + 13 = 24
12 + 14 = 26
13 + 15 = 28
The enumerate
function
enumerate
is another useful function, which provides you with both, the current index and the current value of a given list over which you are iterating:
enumerate(iterable, start=0)
with
iterable
: any object that supports iteration (e.g., lists)start
: the index value from which the counter is to be started, by default it is 0
# Example with enumerate command:
my_list = ['apple', 'windows', 'android', 'linux']
for counter, value in enumerate(my_list):
print(f"counter {counter} relates to entry: {value} = "
f"{my_list[counter]}")
counter 0 relates to entry: apple = apple
counter 1 relates to entry: windows = windows
counter 2 relates to entry: android = android
counter 3 relates to entry: linux = linux
or
for counter, value in enumerate(my_list, 3):
print(f"counter {counter} relates to entry: {value}")
counter 3 relates to entry: apple
counter 4 relates to entry: windows
counter 5 relates to entry: android
counter 6 relates to entry: linux
List comprehension
List comprehension is an elegant way of defining or creating sets in Python that is very close to the mathematical notation of sets. Let’s express for example the expression
(reads: the set of x to the square such that x is an element of the list 0, 1, 2, 3, 4.)
via list comprehension:
result = [ (x*x) for x in [0, 1, 2, 3, 4]]
print(result)
[0, 1, 4, 9, 16]
or even shorter:
print([ (x*x) for x in [0, 1, 2, 3, 4]])
[0, 1, 4, 9, 16]
# instead of:
for x in [0, 1, 2, 3, 4]:
#print(x*x)
print(x**2)
0
1
4
9
16
Note: You have to put the list comprehension into straight brackets, which converts the result into a list. Otherwise the output will be just a so-called “generator object”:
print( (x*x) for x in [0, 1, 2, 3, 4])
<generator object <genexpr> at 0x7fed3801a430>
List comprehension also works with pre-defined lists (sequences):
word_list = ["hello", "this", "is", "a", "list", "comprehension"]
print( [word for word in word_list])
['hello', 'this', 'is', 'a', 'list', 'comprehension']
Summary
The advantage of list comprehension is the reduction of the complexity of your code: you end up with fewer lines in your script. However, this complexity reduction, i.e., putting many commands into one line, might make your code difficult to oversee, especially when you just started to learn programming.