Loops#

(Click here for the German version of this page)

Using the keywords for and while, one can create the two most common kinds of loops, just like in most other programming languages.

But Python slightly differs in the details to other programming languages such as C.

For loop#

In C, a code block inside a for loop will be executed as long as the condition is still fulfilled. For algorithms, one letter index variables are most often used, which are then incremented or decremented. The two most common index variables are i and j.

Python works slightly differently compared to programming languages such as C: The count of executions of the loop are not based on specific conditions, instead it just iterates over an “iterable” object. This is an object, which contains a sequence of values, which can then be iterated over.

In C, one would write a for loop beginning at 0 with a stride (step size) of 1 like this:

for (int i = 0; i < first_index_to_exclude; i++) {
    <Code block>
}

The values for i are calculated as follows. One starts with i = 0 and then increments i until the condition i < first_index_to_exclude does not hold anymore.

In contrast, in Python one would explicitly provide the sequence starting from 0 up until the last element to be included (N-1) as an iterable object, such as a list.

This example in C:

for (int i = 0; i < 5; i++) {
	<Code block>
}

would look like this in Python:

for i in [0, 1, 2, 3, 4]:
	<Code block>

The keyword in is used in this context to have an iterator i over the list [0, 1, 2, 3, 4] with the value at the current element being labeled i.

Convenience with the range() function#

In order to avoid having to write all the indices out like above, the so-called range() function can be used. The first parameter is the number the sequence starts at and the second parameter is the first number, which should not be included in the sequence, just like with list slicing.

By default, the stride (step size) is 1. But it can also be modified by providing a third parameter. It can be both positive or negative. In the latter case one should pay attention that the second argument should be smaller than the first.

range(0, n)

returns a data structure with the values 0 up until (including) n-1. Technically, it is not really a list, but can easily be casted to one using list(range(0, n)). This cast is not necessary for iteration.

A more practical version for the iteration of the above Python example would now be:

for i in range(0, 5):
	<Code block, executed for i=0, i=1, ..., i=4>

As long as the start value is 0, it can be omitted. In this case, the first and only argument will be treated as the upper bound.

my_list = [31, 12, 63, 44, 35]
for i in range(len(my_list)):
	<Code block>

With this, the code block is executed once for all the indices of the list my_list, i.e., for the indices 0 until (including) len(my_list)-1.

If one wants to create a descending for loop, starting at 10 until (inclusive) 3 with a stride of 1, then it can be done so:

for i in range(10, 2, -1):
    <Do something with i>

The loop starts at 10 and goes until (exclusive) 2. Since we want a loop with the values up until (including) 3, we must provide the first value, which should not belong to the sequence, i.e., the number 2. The -1 indicated, that the index should be decremented each execution.

Alternatively, a range can just be reversed directly using the reversed() function. This example also created a loop starting at 10 and ending at 3:

for i in reversed(range(3, 11)):
    <Do something with i>

Iterating over other iterable objects#

Now comes the convenient part for iterating over e.g., a list. In most cases, the index is often not desired. Most of the time, one just wants the given element at the current iteration.

In Python one could do so like this:

for person in people:
    <Do something with person>

If sticking with the way of working in Loops like in C, one could imagine it as if person would be a shortcut for people[i] with i being the index of the current iteration.

One can also work with indices directly, which would look more like C:

for i in range(len(people)):
    <Do something with people[i]>

Since range(len(people)) covers all indices from 0 to len(people)-1, all indices of people are covered.

Iterating over iterable objects with access to indices#

When iterating over an iterable object, like

for person in people:
    <Do something with person>

then one does not have access to the current index. If one still wants to have access to said index, the function enumerate() can be used. This would be the most convenient option for when you need both the index and the object.

The enumerate() function takes the iterable as parameter and returns back an iterable where the for each entry, the first element is the index and the second element is the element of the iterable. By using

for index, element in enumerate(elements):
	<Do something with index and element>

one can access both the given index and given element in each iteration.

While loop#

While loops execute a code block as often as the condition stays fulfilled.

while condition:
	<Code block>

Example:

while n > 0:
	n -= 1

Programming languages such as C have two kinds of while loops. One normal while loop

while(condition) {
	<Code block>
}

and a do-while loop

do {
	<Code block>
} 
while(condition)

The latter one checks the condition only after executing the code block. Said option does not exist in Python. If one wants to imitate the same behavior, then one can work with an infinite loop and a condition break.

The keyword break manually terminates the current loop. In case of an infinite loop, break is the only option to terminate the loop.

while True: # Infinite loop
	<Code block>
	if not condition:
		break

Do-while loops are used more rarely, therefore them missing is not too much of an issue, especially since their behavior can be replicated with the above work-around.

Exercise#

Someone wrote a program in C and something went wrong with the formatting. The indentation was removed. Your task is to translate the code below to Python so that others can compare the respective performance. The disappearance of the indentation surely does not make it easier for the translation.

int result = 0;
for (int i = 0; i < 3; i++) {
result = result + i * 3;
for (int j = 3; j > 1; j--) {
result -= j;    
int k = 5;
while (k > i) {
result += j;
k = k / 2;
}
}
}    
printf("%d", result);
// --> 24

Someone worked on this before you and translated most of the program to Python. Only the loops are missing, indicated by <Loop>. Indentation was also deleted here. The majority of the program was commented out. Uncomment the code and adjust the loops at the given spots. To uncomment the code, remove the two triple quotes(”””). The desired behavior can be seen in the C code above. If you want, you can also optionally get a hint containing the above C code with the correct indentation.

# Replace "<Loop>" with the current Python loops
# Pay attention to correct indentation
result = 0
"""
<Loop>
result = result + i * 3 
<Loop>
result -= j
k = 5
<Loop>
result += j
k = k // 2
"""
print(result)
# Should be 24
0