March 16, 2026 · All About CS
Higher-Order Functions in Python: map, filter, reduce, zip, and sorted
Master Python's most powerful functional tools — map, filter, reduce, zip, and sorted. Learn how higher-order functions eliminate loops, clean up your code, and process data like a pro, with a real-world sales analysis project.
Higher-Order Functions in Python: map, filter, reduce, zip, and sorted
There comes a point in every Python developer's journey where you realize that writing for loops for everything is... verbose. Python offers a cleaner, more expressive way to process collections: higher-order functions. These functions take other functions as arguments and apply them across data — replacing multi-line loops with single, readable expressions.
This guide covers the five higher-order functions you'll use most: map, filter, reduce, zip, and sorted — each explained with practical examples, culminating in a real-world sales data analysis project.
What Are Higher-Order Functions?
In Python, functions are first-class objects. This means you can:
- Pass functions as arguments to other functions
- Return functions from functions
- Assign functions to variables
A higher-order function is any function that either takes a function as an argument or returns a function as its result.
Why use them?
- Concise — replace multi-line loops with single expressions
- Readable — intent is immediately clear (
map= transform,filter= select) - Less error-prone — no manual index management or off-by-one bugs
- Declarative — describe what you want, not how to do it
map() — Transform Every Element
map applies a function to every item in an iterable and returns the results.
map(function, iterable)Basic Example: Squaring Numbers
def square(x):
return x ** 2
numbers = [1, 2, 3, 4, 5]
result = list(map(square, numbers))
print(result) # → [1, 4, 9, 16, 25]Compare this to the loop version:
squared = []
for num in numbers:
squared.append(num ** 2)Same result, but map expresses the intent in one line.
map returns an iterator, not a list. For memory efficiency, map produces results lazily — one at a time as you consume them. Wrap it in list() when you need all results at once.
Practical: Temperature Conversion
def celsius_to_fahrenheit(c):
return (c * 9 / 5) + 32
celsius = [0, 10, 20, 30, 40]
fahrenheit = list(map(celsius_to_fahrenheit, celsius))
print(fahrenheit) # → [32.0, 50.0, 68.0, 86.0, 104.0]map with Multiple Iterables
map can process multiple lists in parallel:
def add(x, y):
return x + y
list1 = [1, 2, 3, 4]
list2 = [10, 20, 30, 40]
result = list(map(add, list1, list2))
print(result) # → [11, 22, 33, 44]Each pair of corresponding elements is passed to the function simultaneously.
filter() — Select What You Need
filter keeps only the items for which a function returns True.
filter(function, iterable)Basic Example: Even Numbers
def is_even(x):
return x % 2 == 0
numbers = [1, 2, 3, 4, 5, 6, 7, 8, 9, 10]
evens = list(filter(is_even, numbers))
print(evens) # → [2, 4, 6, 8, 10]The function is_even returns True for even numbers and False for odd ones. filter keeps only the True results.
Practical: Filtering Strings by Length
def is_long_word(word):
return len(word) > 5
words = ["hi", "hello", "python", "code", "programming", "AI"]
long_words = list(filter(is_long_word, words))
print(long_words) # → ['python', 'programming']Combining map and filter
The real power emerges when you chain these functions:
numbers = [1, 2, 3, 4, 5, 6, 7, 8, 9, 10]
even_squares = list(map(square, filter(is_even, numbers)))
print(even_squares) # → [4, 16, 36, 64, 100]First filter selects even numbers, then map squares them. The data flows through a pipeline — no intermediate variables needed.
reduce() — Aggregate to a Single Value
Unlike map and filter which return collections, reduce collapses an entire iterable into a single value by applying a function cumulatively.
from functools import reduce
reduce(function, iterable)reduce is not a built-in. Unlike map and filter, you must import reduce from the functools module. Python moved it there because Guido van Rossum felt it was overused where simpler alternatives existed.
Basic Example: Sum of a List
from functools import reduce
def add(x, y):
return x + y
numbers = [1, 2, 3, 4, 5]
total = reduce(add, numbers)
print(total) # → 15Here's how reduce processes the list step by step:
Step 1: add(1, 2) → 3
Step 2: add(3, 3) → 6
Step 3: add(6, 4) → 10
Step 4: add(10, 5) → 15It takes the first two elements, applies the function, then uses the result with the next element, and so on — "reducing" the list to a single value.
Practical: Finding the Maximum
numbers = [15, 3, 27, 9, 42, 8]
def find_max(x, y):
return x if x > y else y
maximum = reduce(find_max, numbers)
print(maximum) # → 42Using an Initial Value
The optional third argument provides a starting value:
numbers = [10, 20, 30]
total = reduce(add, numbers, 100)
print(total) # → 160 (100 + 10 + 20 + 30)zip() — Combine Multiple Iterables
zip pairs up corresponding elements from two or more iterables into tuples:
zip(iterable1, iterable2, ...)Basic Example
names = ["Alice", "Bob", "Charlie"]
ages = [25, 30, 35]
combined = list(zip(names, ages))
print(combined)
# → [('Alice', 25), ('Bob', 30), ('Charlie', 35)]Iterating Over Zipped Data
students = ["Alice", "Bob", "Charlie"]
scores = [85, 92, 78]
for name, score in zip(students, scores):
print(f"{name} scored {score}")
# Alice scored 85
# Bob scored 92
# Charlie scored 78No index management, no range(len(...)) — just clean, readable iteration.
Unequal Lengths
zip stops at the shortest iterable:
list1 = [1, 2, 3, 4, 5]
list2 = [10, 20, 30]
result = list(zip(list1, list2))
print(result) # → [(1, 10), (2, 20), (3, 30)] — only 3 tuplesUnzipping with *
You can reverse a zip operation using the unpacking operator *:
pairs = [("Alice", 25), ("Bob", 30), ("Charlie", 35)]
names, ages = zip(*pairs)
print(names) # → ('Alice', 'Bob', 'Charlie')
print(ages) # → (25, 30, 35)sorted() — Advanced Sorting
You already know list.sort() which sorts in place. sorted() is different — it returns a new sorted list without modifying the original, and it works with any iterable, not just lists.
sorted(iterable, key=None, reverse=False)Basic Sorting
numbers = [5, 2, 8, 1, 9, 3]
sorted_numbers = sorted(numbers)
print(sorted_numbers) # → [1, 2, 3, 5, 8, 9]
print(numbers) # → [5, 2, 8, 1, 9, 3] (unchanged)Custom Sort Keys
The key parameter accepts a function that determines the sort criteria:
words = ["python", "is", "awesome", "and", "powerful"]
by_length = sorted(words, key=len)
print(by_length) # → ['is', 'and', 'python', 'awesome', 'powerful']Reverse Sorting
by_length_desc = sorted(words, key=len, reverse=True)
print(by_length_desc) # → ['programming', 'awesome', 'powerful', 'python', 'and', 'is']Sorting Complex Data
students = [
{"name": "Alice", "grade": 92},
{"name": "Bob", "grade": 85},
{"name": "Charlie", "grade": 98},
]
def get_grade(student):
return student["grade"]
by_grade = sorted(students, key=get_grade, reverse=True)
for s in by_grade:
print(f"{s['name']}: {s['grade']}")
# Charlie: 98
# Alice: 92
# Bob: 85Project: Sales Data Analysis Pipeline
Let's combine everything into a real-world data processing pipeline:
from functools import reduce
sales_data = [
{"product": "Laptop", "price": 50000, "quantity": 5, "category": "Electronics"},
{"product": "Mouse", "price": 500, "quantity": 50, "category": "Electronics"},
{"product": "Desk Chair", "price": 8000, "quantity": 10, "category": "Furniture"},
{"product": "Notebook", "price": 50, "quantity": 200, "category": "Stationery"},
{"product": "Keyboard", "price": 1500, "quantity": 30, "category": "Electronics"},
]
print("=" * 50)
print("SALES DATA ANALYSIS PIPELINE")
print("=" * 50)Step 1: Calculate Revenue with map
def calculate_revenue(sale):
return {
"product": sale["product"],
"revenue": sale["price"] * sale["quantity"],
"category": sale["category"],
}
revenues = list(map(calculate_revenue, sales_data))
print("\n1. Product Revenues:")
for item in revenues:
print(f" {item['product']}: ₹{item['revenue']:,}")Step 2: Filter High-Value Products with filter
def is_high_value(item):
return item["revenue"] > 20000
high_value = list(filter(is_high_value, revenues))
print(f"\n2. High-Value Products (>₹20,000):")
for item in high_value:
print(f" {item['product']}: ₹{item['revenue']:,}")Step 3: Calculate Total Revenue with reduce
def sum_revenue(total, item):
return total + item["revenue"]
total_revenue = reduce(sum_revenue, revenues, 0)
print(f"\n3. Total Revenue: ₹{total_revenue:,}")Step 4: Combine Data with zip
products = [item["product"] for item in revenues]
revenue_values = [item["revenue"] for item in revenues]
combined = list(zip(products, revenue_values))
print("\n4. Product-Revenue Pairs:")
for product, revenue in combined:
print(f" {product}: ₹{revenue:,}")Step 5: Rank by Revenue with sorted
def get_revenue(item):
return item["revenue"]
top_products = sorted(revenues, key=get_revenue, reverse=True)
print("\n5. Top Performing Products:")
for i, item in enumerate(top_products, 1):
print(f" {i}. {item['product']}: ₹{item['revenue']:,}")Expected output:
==================================================
SALES DATA ANALYSIS PIPELINE
==================================================
1. Product Revenues:
Laptop: ₹250,000
Mouse: ₹25,000
Desk Chair: ₹80,000
Notebook: ₹10,000
Keyboard: ₹45,000
2. High-Value Products (>₹20,000):
Laptop: ₹250,000
Mouse: ₹25,000
Desk Chair: ₹80,000
Keyboard: ₹45,000
3. Total Revenue: ₹410,000
4. Product-Revenue Pairs:
Laptop: ₹250,000
Mouse: ₹25,000
Desk Chair: ₹80,000
Notebook: ₹10,000
Keyboard: ₹45,000
5. Top Performing Products:
1. Laptop: ₹250,000
2. Desk Chair: ₹80,000
3. Keyboard: ₹45,000
4. Mouse: ₹25,000
5. Notebook: ₹10,000Quick Reference
| Function | Purpose | Returns |
|---|---|---|
map(fn, iterable) | Transform every element | Iterator of transformed values |
filter(fn, iterable) | Keep elements where fn returns True | Iterator of filtered values |
reduce(fn, iterable) | Collapse to a single value | Single accumulated value |
zip(iter1, iter2, ...) | Pair corresponding elements | Iterator of tuples |
sorted(iterable, key=fn) | Sort with custom criteria | New sorted list |
What's Next?
Higher-order functions are your gateway to functional programming in Python. They make data processing pipelines concise, readable, and composable. As you build more complex programs, you'll find yourself reaching for map, filter, and sorted constantly.
With this, you've completed the core Python fundamentals: from variables and data types all the way through OOP, regex, and functional programming. You're now equipped to tackle real-world projects, contribute to open-source codebases, and ace technical interviews.
Happy coding. 🐍