Archived

list comprehensions

An old note — I haven't updated it since I wrote it.

List comprehensions are an exceedingly powerful feature that unlocks Python's functional style.

Squaring items in a list

Let's say we want to square items in a list:

1A = [1,4,6,7,4,3]
2for i in range(len(A)):
3  A[i] = A[i] * A[i]
4print(A) # [1, 16, 36, 49, 16, 9]

This would be the lambda equivalent:

1A = [1,4,6,7,4,3]
2A = [x * x for x in A]
3print(A) # [1, 16, 36, 49, 16, 9]

With a lambda in a list comp:

1A = [1,4,6,7,4,3]
2A = [(lambda n: n * n)(x) for x in A]
3print(A) # [1, 16, 36, 49, 16, 9]

This is the map equivalent:

1A = [1,4,6,7,4,3]
2A = [*map(lambda x: x * x, A)]
3print(A) # [1, 16, 36, 49, 16, 9]

Filtering items in a list

Or let's say we want to filter out values above 5.

1A = [1,4,6,7,4,3]
2A = [x for x in A if x <= 5]
3print(A) # [1, 4, 4, 3]
1A = [1,4,6,7,4,3]
2R = []
3for a in A:
4  if a <= 5:
5      R.append(a)
6print(R) # [1, 4, 4, 3]

Nested list comprehensions

List comprehensions can start to look confusing when they are nested.

1A = [L + N for L in 'ABC' for N in '123']
2print(A)

Note: consider adding conditional nested

Output:

1['A1', 'A2', 'A3', 'B1', 'B2', 'B3', 'C1', 'C2', 'C3']

Looking at the output, we can see this list comprehension is equivalent to:

1A = []
2for L in 'ABC':
3  for N in '123':
4  A.append(L + N)
5print(A)

Try writing complex and nested list comprehensions, and colour-coding them. Doing so makes it much easier reading them down the line.

list comp

Please note that list comprehensions return a copy of your list. In other words, they are hungry in terms of memory usage. This problem can, however, be obviated via the use of generator expressions.