The for loop

7. The for loop#

7.1. Overview#

We introduced the concept of tuples, strings, and ranges. Now, it’s time to explore how to manipulate the elements within these sequences. To achieve this, we need to use the “for each” loop (see glossary For Each), commonly referred to as the for loop in Python.

The for loop allows us to execute a set of instructions for each element within a sequence. For instance, consider a scenario where we want to display all the vowels in a given string. Here’s how the for loop can be used to achieve that:

sentence = input()
for character in sentence:
    if character in "aeiouyAEIOUY":
        print(character)

In this example, the loop is composed of two main parts: the loop declaration (for character in sentence:) and the block of code to be executed. The operation is straightforward: each character in the sequence sentence is sequentially assigned to the variable character. For every value assigned to character, the instructions in the code block are executed. In this case, if the character is a vowel, it is printed.

The general syntax of a for loop in Python is as follows:

for variable in sequence:
    # instructions to execute
    ...
    ...

The for loop can be used with any iterable sequence, including str, tuple, range and list (we will present this type really soon). It can even work with more complex data structures. The loop iterates over each element in the sequence, allowing us to perform operations on each element individually.

Example with a Tuple

Here’s an example that demonstrates how to iterate over a tuple containing the months of the year:

>>> year = ("January", "February", "March", "April", "May", "June", "July", "August", "September", "October", "November", "December")
>>> for month in year:
>>>     print(month)
January
February
March
April
May
June
July
August
September
October
November
December

In this example, the loop iterates over each month in the tuple and prints it. This is a simple way to handle fixed collections of data.

Another powerful use of the for loop is with range, which generates a sequence of numbers and is especially useful when you need to iterate over a series of numbers with a specific pattern.

>>> for i in range(2, 10, 2):
>>>     print(i**2)
4
16
36
64

In this case, range(2, 10, 2) generates the sequence 2, 4, 6, 8. The loop then iterates over each of these numbers, computes its square using i**2, and prints the result.

The for loop is a fundamental control structure in Python and is versatile enough to handle a wide range of tasks, from simple iterations over basic data types to more complex operations involving nested loops or combined with other constructs like if statements. It is also important to note that the for loop can be combined with the enumerate() function to retrieve both the index and the value from a sequence, or with the zip() function to iterate over multiple sequences in parallel.

7.2. enumerate#

The enumerate function (see glossary Enumerate) is a built-in Python function that adds a counter to an iterable and returns it as an enumerate object. This is especially useful when you need to loop through a sequence and also keep track of the index of each element.

Consider a situation where you want to print each element of a list along with its index. You can do it the hard way.

fruits = ["apple", "banana", "cherry", "date"]

for index in range(len(fruits)):
    print(f"Index {index}: {fruits[index]}")

Output:

Index 0: apple
Index 1: banana
Index 2: cherry
Index 3: date

Or the easy way…

fruits = ["apple", "banana", "cherry", "date"]

for index, fruit in enumerate(fruits):
    print(f"Index {index}: {fruit}")

In this example, the enumerate(fruits) call provides both the index and the element at each step of the loop. The loop variable index gets the position, and fruit gets the corresponding item in the list. This is a more readable and Pythonic way to access both the index and the item, compared to manually tracking the index with an additional counter.

7.3. zip#

The zip function (see glossary Zip) is another built-in Python function that takes two or more sequences and returns an iterator of tuples, where the first tuple contains the first elements of each sequence, the second tuple contains the second elements, and so on. This is useful when you want to iterate over multiple sequences simultaneously.

Suppose you have two lists, one containing names and another containing corresponding ages. You can use zip to pair them together.

names = ["Alice", "Bob", "Charlie"]
ages = [24, 30, 22]

for name, age in zip(names, ages):
    print(f"{name} is {age} years old.")

Output:

Alice is 24 years old.
Bob is 30 years old.
Charlie is 22 years old.

In this example, zip(names, ages) creates an iterator that produces tuples like ("Alice", 24), ("Bob", 30), and ("Charlie", 22), allowing you to iterate over both lists simultaneously in a single loop.

If the sequences passed to zip() are of different lengths, the iteration stops as soon as the shortest sequence is exhausted. For example:

names = ["Alice", "Bob", "Charlie", "Diana"]
ages = [24, 30]

for name, age in zip(names, ages):
    print(f"{name} is {age} years old.")

Output:

Alice is 24 years old.
Bob is 30 years old.

In this case, since the ages list has only two elements, the loop only runs twice, pairing "Alice" with 24 and "Bob" with 30. "Charlie" and "Diana" are not included because there are no corresponding ages.

Note

Note that this example is not necessarily ideal. With the introduction of objects, we will discover a more robust way to store and manipulate information related to a group of people or entities. Objects allow us to group both data and associated methods, offering better structuring and greater flexibility for managing complex information.