sec03 - Python for Loop Advanced Guide: enumerate(), zip(), sorted(), and itertools Explained
スポンサーリンク

Useful Functions for for Loops

When working with iterable objects (like lists or ranges) in a for loop, you can write more efficient and readable code by combining built-in functions and itertools utilities, rather than simply iterating through elements in order. This section explains in detail what each function returns, how to receive the values inside a for block, and important notes. Sample code and execution results (in code blocks) are also provided.

1. enumerate()

enumerate() generates an iterator that returns tuples (index, item) containing both the index (a number) and the corresponding element from an iterable. When using it in a for loop, it’s common to unpack these values into index and item. You can specify the starting index using the start argument.

items = ['apple','banana','cherry']

# enumerate() generates an iterator that returns tuples (index, item)
for index, item in enumerate(items, start=1):
    print(f'The {index}th item is {item}')
The 1st item is apple
The 2nd item is banana
The 3rd item is cherry

Note: The returned object is an iterator (lazy). You can convert it into a list with list(enumerate(iterable)) if necessary, but in most cases, iterating directly with a for loop is more memory-efficient.

スポンサーリンク

2. sorted()

sorted() returns a new list containing all elements of the iterable in sorted order. The original object remains unchanged. By default, sorting is in ascending order, but you can specify reverse=True for descending order. For custom sorting criteria, use the key= argument (e.g., key=lambda x: x[1]).

numbers = [5, 2, 9, 1]

# Loop in ascending order (sorted() returns a new list)
for num in sorted(numbers):
    print(f'The number is {num}')

# Loop in descending order (specify reverse=True)
for num in sorted(numbers, reverse=True):
    print(f'The number in descending order is {num}')
The number is 1
The number is 2
The number is 5
The number is 9
The number in descending order is 9
The number in descending order is 5
The number in descending order is 2
The number in descending order is 1

Note: Since the sorted result is returned as a new list, you can process it while preserving the original order of data. However, frequently sorting large datasets can increase processing costs, so it’s best to sort only where necessary.

3. reversed()

reversed() returns an iterator that iterates over a sequence (like a list, tuple, or string) in reverse order. The original sequence itself remains unchanged. In a for loop, you simply receive and process each element as usual.

names = ['Alice','Bob','Charlie']

for name in reversed(names):
    print(f'The name in reverse order is {name}')
The name in reverse order is Charlie
The name in reverse order is Bob
The name in reverse order is Alice

Note: reversed() works on sequence types. It may not be available for all iterables. If necessary, you can explicitly convert the object into a sequence with list() before using it.

4. zip()

zip() generates an iterator that aggregates elements from multiple iterables into tuples (e.g., (a, b)). It’s common to unpack these values in a for loop. The loop ends when the shortest iterable is exhausted (extra elements in longer iterables are ignored).

names = ['Alice','Bob']
ages = [25, 30, 35]  # ages is longer

for name, age in zip(names, ages):
    print(f'{name} is {age} years old')
Alice is 25 years old
Bob is 30 years old

Note: In this example, ages has one extra element (35), which is ignored. If you want to keep unmatched elements, consider using zip_longest() described next.

5. itertools.zip_longest()

itertools.zip_longest() works like zip() but allows you to iterate over iterables of different lengths. Missing values from shorter iterables are filled with a specified fillvalue. Each iteration returns a tuple.

from itertools import zip_longest

names = ['Alice','Bob','Charlie']
ages = [25, 30]  # ages is shorter

for name, age in zip_longest(names, ages, fillvalue='-'):
    print(f'{name} is {age} years old')
Alice is 25 years old
Bob is 30 years old
Charlie is - years old

Note: In this example, Charlie has no corresponding age in ages, so fillvalue='-' is assigned to age. You can use any value for fillvalue (e.g., None or a string).

6. itertools.chain()

itertools.chain() returns an iterator that treats multiple iterables as a single iterable. You can pass lists, tuples, or other iterable types directly, without needing to convert them beforehand. In a for loop, you can simply process each element in sequence.

from itertools import chain

list1 = [1, 2]
tuple1 = (3, 4)
set1 = {5, 6}  # Note: the order of elements in a set is not guaranteed

for num in chain(list1, tuple1, set1):
    print(f'The element is {num}')
The element is 1
The element is 2
The element is 3
The element is 4
The element is 5
The element is 6

Note: In the above example, set is included, but since sets do not preserve order, the output sequence may vary by environment. If order is important, use an ordered iterable (like a list or tuple) or sort it beforehand.

スポンサーリンク