How to Use Multiple "for" in a Python List Comprehension?

In Python, the list comprehension syntax allows adding one or more for clauses to a list comprehension after the main for clause.

Multiple for clauses in a list comprehension allow you to iterate over multiple iterables in a single expression and can be used to create a list of all possible combinations of the elements in the iterables.

Syntax

You can use the following syntax:

new_list = [expression for item_1 in iterable_1 ... for item_n in iterable_n]

Where:

  • expression is the expression that will be evaluated and included in the resulting list;
  • item_1 to item_n are the loop variables that will be assigned values from their respective iterables, iterable_1 to iterable_n.

Each for loop is separated by a "for" keyword, where the outer loop iterates over the first iterable, the inner loop iterates over the second iterable, and so on. Please note that this is slightly different from using multiple nested list comprehensions.

Examples

For example, consider the following list comprehension that uses two for loops to create a combination of all elements of two existing lists into a new list (which contains all possible combinations of their elements as tuples):

list1 = ['a', 'b']
list2 = [1, 2]
new_list = [(x, y) for x in list1 for y in list2]

print(new_list) # [('a', 1), ('a', 2), ('b', 1), ('b', 2)]

This is equivalent to:

list1 = ['a', 'b']
list2 = [1, 2]
new_list = []

for x in list1:
    for y in list2:
        new_list.append((x, y))

print(new_list) # [('a', 1), ('a', 2), ('b', 1), ('b', 2)]

In these examples, the first loop iterates over list1 and the second loop iterates over list2, so the resulting tuples have the form (x, y). If you were to reverse the order of the loops, the resulting tuples would have the form (y, x) instead:

list1 = ['a', 'b']
list2 = [1, 2]
new_list = [(x, y) for x in list2 for y in list1]

print(new_list) # [(1, 'a'), (1, 'b'), (2, 'a'), (2, 'b')]

As you can see from the example above, the order of the for clauses in the list comprehension is important, as it determines the order in which the elements are combined.

This is equivalent to:

list1 = ['a', 'b']
list2 = [1, 2]
new_list = []

for x in list2:
    for y in list1:
        new_list.append((x, y))

print(new_list) # [(1, 'a'), (1, 'b'), (2, 'a'), (2, 'b')]

Another use case for multiple for clauses in a list comprehension is when you need to iterate over nested data structures, like a list of lists or a dictionary of lists, for example, like the following:

matrix = [[1, 2, 3], [4, 5, 6], [7, 8, 9]]
flattened = [num for row in matrix for num in row]

print(flattened) # [1, 2, 3, 4, 5, 6, 7, 8, 9]

This is equivalent to:

matrix = [[1, 2, 3], [4, 5, 6], [7, 8, 9]]
flattened = []

for row in matrix:
    for num in row:
        flattened.append(num)

print(flattened) # [1, 2, 3, 4, 5, 6, 7, 8, 9]

Using Multiple for Clauses With if Clause:

A list comprehension can have multiple for clauses, which are followed by zero or more if clauses.

For example, consider the following list comprehension that combines the elements of two lists only if they are not equal:

points = [(x, y) for x in [1, 2, 3] for y in [3, 1, 4] if x != y]

print(points) # [(1, 3), (1, 4), (2, 3), (2, 1), (2, 4), (3, 1), (3, 4)]

This is equivalent to:

points = []

for x in [1, 2, 3]:
    for y in [3, 1, 4]:
        if x != y:
            points.append((x, y))

print(points) # [(1, 3), (1, 4), (2, 3), (2, 1), (2, 4), (3, 1), (3, 4)]

This post was published by Daniyal Hamid. Daniyal currently works as the Head of Engineering in Germany and has 20+ years of experience in software engineering, design and marketing. Please show your love and support by sharing this post.