Section 1: List Comprehensions

 Table of Contents > Chapter 4 > Section 1 

Designing with List Comprehensions

In CPSC 110 you were introduced to the abstract list processing functions map, filter and fold.  Recall that map and filter both produced something of type (listof X).  In this section of the course, we introduce you to list comprehensions - the Python equivalent of map and filter

In general, a list comprehension has the form:

[expr for x in lox if bExpr]

where expr is an expression and bExpr is a Boolean expression, both of which involve x, in general.  This list comprehension produces a value that is equivalent to the value of res after the following code segment has executed:

res = []
for x in lox:
    if bExpr:
        res = res + [expr]

Note that the if-clause is optional. 

Let's consider some examples:

>>> loi = [4, -3, 5, 7, 2]

>>> [2 * i for i in loi]
[8, -6, 10, 14, 4]

>>> [i for i in loi if i > 0]
[4, 5, 7, 2]

>>> [2 * i for i in loi if i > 2]
[8, 10, 14]


In Code Explorer 4.1 we present two versions of a function that consumes a list of strings and that produces a list of the lengths of those strings.  One uses a for-each loop and the other a list comprehension. 

Note that a function designed with a list comprehension will generally execute faster than an equivalent function that uses a for-each loop.  The table below compares execution times for 1,000,000 calls to the two functions presented in Code Explorer 4.1 when a list containing 250 strings is passed as a parameter.   The function that uses a list comprehension (lostr_len_lcomp) clearly executes much more quickly. 

lostr_len_loop
lostr_len_lcomp
226.01 seconds
28.06 seconds

List Comprehensions and Nested Loops

Note that it is possible to construct a list comprehension that is equivalent to code that uses nested for-each loops.  So, for example, the following code segment:

loi_x = [1, 2]
loi_y = [2, 3, 4]
res = []

for x in loi_x:
    for y in loi_y:
        res = res + [x * y]


can be replaced with:

res = [x * y for x in loi_x for y in loi_y]

so that in each case, the value assigned to res is:

[2, 3, 4, 4, 6, 8]
Observe that the order in which the for statements appear in both segments of code is the same.  Also note that an if-clause can optionally be associated with each of the for statements.


Review 4.1: List Comprehensions

Question 1 of 3

What list is produced by the following?

loi = [3, 9, 0, -2, 5, -1]
[max(i, 0) for i in loi]


[0, 0, 0, -2, 0, -1]

[3, 9, 0, 0, 5, 0]

[3, 9, 0, 5]