Skip to main content

Python map(), filter(), reduce(), and Higher-Order Functions

Intermediate25 min7 exercises100 XP
0/7 exercises

Picture an assembly line in a factory. Raw materials enter at one end. At the first station, each piece is shaped. At the next station, defective pieces are removed. At the final station, all the good pieces are combined into one finished product.

Python has three functions that work exactly like this assembly line: map() transforms every item, filter() keeps only the items you want, and reduce() combines everything into a single result. Together, they let you process collections of data in a clean, readable way.

In this tutorial, you'll learn how these tools work, when to use them, and when a list comprehension might be a better choice. By the end, you'll be writing data pipelines that would make a factory foreman proud.

What Are Higher-Order Functions?

A higher-order function is a function that takes another function as an argument, or returns a function as its result. That's it.

You've already used one without realizing it. The built-in sorted() function has a key parameter where you pass in a function:

sorted() is a higher-order function
Loading editor...

Here, len is passed as an argument to sorted(). The sorted function calls len on each item to decide the order. You didn't call len() yourself — you just told sorted which function to use.

map(), filter(), and reduce() all work this way. You give them a function and a collection, and they apply that function to the items. That's what makes them higher-order functions.

map() — Transform Every Item

map() takes a function and an iterable (like a list), applies the function to every item, and returns the transformed results. Think of it as the "shaping station" on our assembly line.

The syntax is: map(function, iterable). It returns a map object, which you usually convert to a list.

Using map() to double every number
Loading editor...

map(double, numbers) calls double(1), double(2), double(3), and so on. It collects all the results. The list() wrapper converts the map object into a regular list so we can print it.

Since writing a whole function just to double a number feels heavy, map() is often paired with a lambda — a tiny anonymous function:

map() with lambda and built-in functions
Loading editor...

You can pass any function to map() — your own functions, lambdas, or built-ins like str.upper, round, len, or int.

filter() — Keep Only What You Need

filter() takes a function and an iterable. The function must return True or False for each item. Only items where the function returns True are kept. Think of it as quality control on the assembly line — defective pieces are removed.

Using filter() to keep even numbers
Loading editor...

filter(is_even, numbers) calls is_even(1) which returns False (so 1 is dropped), is_even(2) returns True (so 2 is kept), and so on. Only the items that pass the test survive.

More filter() examples
Loading editor...

Passing bool to filter() is a neat trick. Empty strings, zero, None, and empty lists are all "falsy" in Python — bool() returns False for them. So filter(bool, items) removes all falsy values.

Combining map() and filter()

The real power comes from chaining these together. Filter first to select items, then map to transform them — just like stations on an assembly line.

Chaining filter() and map()
Loading editor...

Since both filter() and map() are lazy, you can chain them without creating intermediate lists. The data flows through the pipeline efficiently.

Here is a more practical example — processing a list of product prices:

Practical pipeline: filter then transform
Loading editor...

reduce() — Combine All Items Into One

reduce() takes a function and an iterable, then combines all items into a single value. It's the final station on the assembly line — all the pieces get assembled into one product.

Unlike map() and filter(), reduce() is not a built-in. You need to import it from the functools module.

Using reduce() to combine values
Loading editor...

Here's how reduce() works step by step for the sum. The function takes two arguments: the accumulated result so far (a) and the next item (b):

  • Start with the first two items: a=1, b=2 gives 3
  • Take that result and the next item: a=3, b=3 gives 6
  • Continue: a=6, b=4 gives 10
  • Finally: a=10, b=5 gives 15
  • More reduce() examples
    Loading editor...

    map/filter vs List Comprehensions

    Python offers another way to transform and filter lists: list comprehensions. They often produce more readable code than map() and filter(). Let's compare.

    Using map() and filter()
    numbers = [1, 2, 3, 4, 5, 6]
    
    # Double even numbers
    evens = filter(lambda x: x % 2 == 0, numbers)
    result = list(map(lambda x: x * 2, evens))
    print(result)  # [4, 8, 12]
    Using a list comprehension
    numbers = [1, 2, 3, 4, 5, 6]
    
    # Double even numbers
    result = [x * 2 for x in numbers if x % 2 == 0]
    print(result)  # [4, 8, 12]

    The list comprehension does both filtering and mapping in a single, readable line. For simple transformations, comprehensions are usually the better choice in Python.

    So when should you use map() and filter()? They're useful when you already have a named function to apply:

    map() shines with named functions
    Loading editor...

    Practice Exercises

    Time to practice. These exercises start with individual functions and build up to combining them in pipelines. Remember to wrap map() and filter() in list() when printing.

    Exercise 1: Square Every Number
    Write Code

    Use map() with a lambda to square every number in the list [1, 2, 3, 4, 5].

    Print the result as a list.

    Expected output:

    [1, 4, 9, 16, 25]
    Loading editor...
    Exercise 2: Filter Out Short Words
    Write Code

    Use filter() with a lambda to keep only words that have more than 3 characters.

    Given: ["hi", "hello", "hey", "world", "ok", "python"]

    Print the result as a list.

    Expected output:

    ['hello', 'world', 'python']
    Loading editor...
    Exercise 3: Predict the Pipeline Output
    Predict Output

    Read this code and predict the output. Then write a print() statement that produces the exact same output.

    numbers = [10, 25, 30, 45, 50]
    result = list(map(lambda x: x // 10, filter(lambda x: x >= 30, numbers)))
    print(result)

    Think step by step: what does filter keep, then what does map do to each item?

    Loading editor...
    Exercise 4: Fix the Broken Pipeline
    Fix the Bug

    This code should convert a list of temperature strings like ["32F", "100F", "212F"] into Celsius integers. But it has two bugs.

    Expected output:

    [0, 37, 100]

    Formula: Celsius = (Fahrenheit - 32) * 5 / 9, then round to the nearest integer.

    Loading editor...
    Exercise 5: Find the Product with reduce()
    Write Code

    Use reduce() from the functools module to calculate the product of all numbers in the list [2, 3, 4, 5].

    The product is 2 * 3 * 4 * 5 = 120.

    Print the result.

    Expected output:

    120
    Loading editor...
    Exercise 6: Build a Data Pipeline
    Write Code

    Given a list of student scores, build a pipeline that:

    1. Filters out failing scores (keep only scores >= 60)

    2. Curves each passing score by adding 10 (use map)

    3. Caps scores at 100 (use map with min)

    Given: [45, 82, 55, 91, 67, 38, 73, 95]

    Print the final list.

    Expected output:

    [92, 100, 77, 83, 100]

    Hint: to cap at 100, use min(score, 100).

    Loading editor...
    Exercise 7: Refactor to a List Comprehension
    Refactor

    Refactor this map/filter pipeline into a single list comprehension that produces the same output.

    Original code:

    words = ["Hello", "WORLD", "Python", "CODE", "test"]
    result = list(map(str.lower, filter(lambda w: len(w) > 4, words)))

    Write a list comprehension that produces the same result and print it.

    Expected output:

    ['hello', 'world', 'python']
    Loading editor...

    Summary

    Here's what you've learned about functional tools in Python:
    ---------
    map(fn, iterable)Transform every itemMap object (lazy)
    filter(fn, iterable)Keep items where fn returns TrueFilter object (lazy)
    reduce(fn, iterable)Combine all items into one valueSingle value
    Higher-order functionA function that takes or returns a functionDepends on the function

    The practical takeaway: use list comprehensions for most transform/filter tasks in Python. Reach for map() and filter() when you have a named function to apply or need lazy evaluation. Use reduce() sparingly — Python's built-ins cover most cases better.

    What's Next?

    You now have a strong foundation in Python functions. Next, explore [Error Handling](/python/python-try-except) to learn how to write code that handles mistakes gracefully instead of crashing.