Skip to content

Map Filter Reduce

Mental Model

map transforms every element, filter selects elements that pass a test, and reduce collapses a sequence into a single value. Together they form the classic functional trio: transform, select, accumulate. In modern Python, list comprehensions often replace map and filter, but understanding these primitives clarifies how data flows through pipelines.

map()

1. Transform Elements

python numbers = [1, 2, 3, 4, 5] squared = list(map(lambda x: x**2, numbers)) print(squared) # [1, 4, 9, 16, 25]

2. Multiple Iterables

python a = [1, 2, 3] b = [10, 20, 30] result = list(map(lambda x, y: x + y, a, b)) print(result) # [11, 22, 33]

3. Lazy Iterator

map() returns an iterator, not a list. Values are computed on demand.

python numbers = [1, 2, 3, 4] squares = map(lambda x: x**2, numbers) print(squares) # <map object at 0x...> print(list(squares)) # [1, 4, 9, 16]

filter()

1. Select Elements

python numbers = [1, 2, 3, 4, 5, 6] evens = list(filter(lambda x: x % 2 == 0, numbers)) print(evens) # [2, 4, 6]

2. Lazy Iterator

filter() also returns an iterator.

python numbers = [1, 2, 3, 4, 5, 6] evens = filter(lambda x: x % 2 == 0, numbers) print(evens) # <filter object at 0x...> print(list(evens)) # [2, 4, 6]

reduce()

1. Accumulate

```python from functools import reduce

numbers = [1, 2, 3, 4, 5] total = reduce(lambda x, y: x + y, numbers) print(total) # 15 ```

2. With Initial

python product = reduce(lambda x, y: x * y, numbers, 1) print(product) # 120

Comprehensions Alternative

1. More Pythonic

```python

map equivalent

squared = [x**2 for x in numbers]

filter equivalent

evens = [x for x in numbers if x % 2 == 0] ```

Functional Composition

Chain filter, map, and reduce for data pipelines.

1. Pipeline Example

```python from functools import reduce

names = ["Alice", "Bob", "Charlie", "David"]

filter → map → reduce

result = reduce( lambda a, b: a + " & " + b, map(str.upper, filter(lambda name: len(name) > 4, names)) )

print(result) # ALICE & CHARLIE & DAVID ```

2. Step by Step

```python from functools import reduce

numbers = [1, 2, 3, 4, 5, 6]

Step 1: filter evens

evens = filter(lambda x: x % 2 == 0, numbers)

Step 2: map to squares

squares = map(lambda x: x ** 2, evens)

Step 3: reduce to sum

total = reduce(lambda x, y: x + y, squares)

print(total) # 56 (4 + 16 + 36) ```

Summary

  • map: transform
  • filter: select
  • reduce: accumulate
  • Comprehensions often better

Exercises

Exercise 1. Given a list of dictionaries [{"name": "Alice", "score": 85}, {"name": "Bob", "score": 42}, {"name": "Charlie", "score": 91}], use filter() to keep only entries with score >= 60, then use map() to extract just the names. Print the resulting list.

Solution to Exercise 1
students = [
    {"name": "Alice", "score": 85},
    {"name": "Bob", "score": 42},
    {"name": "Charlie", "score": 91},
]

passing = filter(lambda s: s["score"] >= 60, students)
names = list(map(lambda s: s["name"], passing))
print(names)  # ['Alice', 'Charlie']

Exercise 2. Use functools.reduce to implement a function my_max(numbers) that finds the maximum value in a list without using the built-in max(). Handle the empty-list case by raising ValueError.

Solution to Exercise 2
from functools import reduce

def my_max(numbers):
    if not numbers:
        raise ValueError("my_max() arg is an empty sequence")
    return reduce(lambda a, b: a if a > b else b, numbers)

print(my_max([3, 1, 4, 1, 5, 9, 2, 6]))  # 9
print(my_max([-5, -2, -8]))                 # -2
try:
    my_max([])
except ValueError as e:
    print(e)

Exercise 3. Rewrite the following pipeline using list comprehensions instead of map and filter: python result = list(map(str, filter(lambda x: x % 2 == 0, map(lambda x: x ** 2, range(10))))) Verify both versions produce the same output.

Solution to Exercise 3
# Original with map/filter
result1 = list(
    map(str, filter(lambda x: x % 2 == 0, map(lambda x: x ** 2, range(10))))
)

# Comprehension version
result2 = [str(x ** 2) for x in range(10) if (x ** 2) % 2 == 0]

print(result1)
print(result2)
print(result1 == result2)  # True