Python · comprehensions

List Comprehensions

Build a new list from an iterable in one readable line: transform each item, and optionally filter.

Reading a comprehension

[x**2 for x in range(10) if x % 2 == 0]

for clause

Runs first: where the items come from, one at a time.

condition (optional)

Checked next: items that fail it are skipped.

expression

Written first, computed last: what goes into the new list for each kept item.

Basic list comprehension


          # basic comprehension
          squares = [x**2 for x in range(5)]
          # ans: [0, 1, 4, 9, 16]
        

With a transformation


          # transform items
          words = ["hello", "world"]
          upper = [word.upper() for word in words]
          # ans: ['HELLO', 'WORLD']
        

With a condition (filter)


          # filter with condition
          evens = [x for x in range(10) if x % 2 == 0]
          # ans: [0, 2, 4, 6, 8]
        

Multiple conditions


          # multiple filters
          numbers = [x for x in range(20)
                     if x % 2 == 0
                     if x % 3 == 0]
          # ans: [0, 6, 12, 18]
        

Two if clauses must both pass, like and.

If-else expression


          # if-else (not filter)
          result = ["even" if x % 2 == 0 else "odd"
                    for x in range(5)]
          # ans: ['even', 'odd', 'even', 'odd', 'even']
        

An if-else before for chooses a value for every item; an if after for drops items.

Nested loops


          # nested loops
          pairs = [(x, y) for x in range(3)
                          for y in range(2)]
          # ans: [(0,0), (0,1), (1,0), (1,1), (2,0), (2,1)]
        

The first for is the outer loop: y runs through all its values for each x.

Flatten a nested list


          # flatten
          nested = [[1, 2], [3, 4], [5, 6]]
          flat = [item for sublist in nested
                       for item in sublist]
          # ans: [1, 2, 3, 4, 5, 6]
        

Exercises

Predict the list, then press → to check.

Exercise 1


        # basic comprehension?
        [x*2 for x in range(3)]
        # ans: [0, 2, 4]
      

Exercise 2


        # with filter?
        [x for x in range(10) if x > 5]
        # ans: [6, 7, 8, 9]
      

Exercise 3


          # if-else position?
          [x if x > 0 else 0 for x in [-1, 1, -2, 2]]
          # ans: [0, 1, 0, 2]
        

Exercise 4


        # nested comprehension?
        [[i*j for j in range(3)] for i in range(2)]
        # ans: [[0, 0, 0], [0, 1, 2]]
      

The inner comprehension builds one whole row for each i.

Exercise 5


        # string comprehension?
        [c.upper() for c in "abc"]
        # ans: ['A', 'B', 'C']
      

Exercise 6


          # multiple filters?
          [x for x in range(20) if x % 2 == 0 if x % 5 == 0]
          # ans: [0, 10]
        

Exercise 7

Comprehension vs loop?


          [x**2 for x in range(3)]
        

          result = []
          for x in range(3):
              result.append(x**2)
        

Same result: [0, 1, 4]. The comprehension is shorter and builds the list for you.

Exercise 8


        # empty comprehension?
        [x for x in range(0)]
        # ans: []
      

Exercise 9


        # tuple in comprehension?
        [(x, x**2) for x in range(3)]
        # ans: [(0, 0), (1, 1), (2, 4)]
      

Exercise 10


          # flatten with condition?
          nested = [[1,2,3], [4,5,6]]
          [x for sublist in nested
             for x in sublist if x % 2 == 0]
          # ans: [2, 4, 6]
        

Remember

Shape

[expression for item in iterable if condition]

Filter vs choose

if after for drops items; a if c else b before for picks a value.

Loops nest left to right

The first for is the outer loop, as in the equivalent nested loops.

Keep it readable

If it no longer fits on a line or two, write the loop instead.