Double Iteration in List Comprehension

Here’s something I didn’t know possible in Python: iteration over more than one iterable in a list comprehension:

>>> seq_x = [1, 2, 3, 4]
>>> seq_y = 'abc'
>>> [(x,y) for x in seq_x for y in seq_y]
[(1, 'a'), 
 (1, 'b'), 
 (1, 'c'), 
 (2, 'a'), 
 (2, 'b'), 
 (2, 'c'), 
 (3, 'a'), 
 (3, 'b'), 
 (3, 'c'), 
 (4, 'a'), 
 (4, 'b'), 
 (4, 'c')]

Cool, isn’t it? It’s equivalent to the following snippet:

>>> result = [] 
... for x in seq_x: 
...     for y in seq_y:  
...         result.append((x,y)) 
>>> result 
[(1, 'a'), 
 (1, 'b'), 
 (1, 'c'), 
 (2, 'a'), 
 (2, 'b'), 
 (2, 'c'), 
 (3, 'a'), 
 (3, 'b'), 
 (3, 'c'), 
 (4, 'a'), 
 (4, 'b'), 
 (4, 'c')]

It also supports both “if” statements and referencing the outer iterator from the inner one, like so:

>>> seq = ['abc', 'def', 'g', 'hi'] 
... [y for x in seq if len(seq) > 1 for y in x if y != 'e'] 
['a', 'b', 'c', 'd', 'f', 'g', 'h', 'i']

This is equivalent to the snippet:

>>> result = [] 
... for x in seq: 
...     if len(seq) > 1: 
...         for y in x: 
...             if y != 'e': 
...                 result.append(y) 
... result 
['a', 'b', 'c', 'd', 'f', 'g', 'h', 'i']

The thing you should notice here, is that the outer loop is the first ‘for’ loop in the list comprehension. This was a little confusing for me at first because when I nest list comprehensions it’s the other way around.

To read more about this feature, check out this StackOverflow thread or the Python Manual.

Discuss this post at the comment section below.
Follow me on Twitter , Facebook or Google+

Similar Posts