Home > Articles

This chapter is from the book

This chapter is from the book

5.19 Map, Filter, and Reduce

Programmers familiar with functional languages often inquire about common list operations such as map, filter, and reduce. Much of this functionality is provided by list comprehensions and generator expressions. For example:

def square(x):
    return x * x

nums = [1, 2, 3, 4, 5]
squares = [ square(x) for x in nums ]    # [1, 4, 9, 16, 25]

Technically, you don’t even need the short one-line function. You could write:

squares = [ x * x for x in nums ]

Filtering can also be performed with a list comprehension:

a = [ x for x in nums if x > 2 ]    # [3, 4, 5]

If you use a generator expression, you’ll get a generator that produces the results incrementally through iteration. For example:

squares = (x*x for x in nums)    # Creates a generator
for n in squares:
    print(n)

Python provides a built-in map() function that is the same as mapping a function with a generator expression. For example, the above example could be written:

squares = map(lambda x: x*x, nums)
for n in squares:
    print(n)

The built-in filter() function creates a generator that filters values:

for n in filter(lambda x: x > 2, nums):
    print(n)

If you want to accumulate or reduce values, you can use functools.reduce(). For example:

from functools import reduce
total = reduce(lambda x, y: x + y, nums)

In its general form, reduce() accepts a two-argument function, an iterable, and an initial value. Here are a few examples:

nums = [1, 2, 3, 4, 5]
total = reduce(lambda x, y: x + y, nums)         # 15
product = reduce(lambda x, y: x * y, nums, 1)    # 120

pairs = reduce(lambda x, y: (x, y), nums, None)
# (((((None, 1), 2), 3), 4), 5)

reduce() accumulates values left-to-right on the supplied iterable. This is known as a left-fold operation. Here is pseudocode for reduce(func, items, initial):

def reduce(func, items, initial):
    result = initial
    for item in items:
        result = func(result, item)
    return result

Using reduce() in practice may be confusing. Moreover, common reduction operations such as sum(), min(), and max() are already built-in. Your code will be easier to follow (and likely run faster) if you use one of those instead of trying to implement common operations with reduce().

InformIT Promotional Mailings & Special Offers

I would like to receive exclusive offers and hear about products from InformIT and its family of brands. I can unsubscribe at any time.