New: 6 free SQL practice datasets with 300+ questions — try the SQL Compiler →
Python

Python lambda, map, filter and reduce Explained

Python lambda, map, filter and reduce explained with real code and output: sort keys, lazy iterators, reduce steps and when to use comprehensions.

Upskly AI Team September 26, 2026 9 min read
Python lambda, map, filter and reduce Explained

A lambda is a small anonymous function written in a single expression: lambda x: x * 2. It is most useful when you need a throwaway function to hand to another function. map() applies a function to every item, filter() keeps only the items for which a function returns true, and reduce() (from functools) combines all the items into a single value.

This guide explains each with real output, shows when a comprehension is the better choice, and covers the traps.

In this guide

The short version

  • lambda args: expression – a tiny function with no name and one expression.
  • map(f, items) – apply f to each item.
  • filter(f, items) – keep items where f(item) is true.
  • reduce(f, items) – combine items pairwise into one value (import it from functools).
  • map and filter return lazy iterators: wrap them in list() to see the results.

What is a lambda?

A lambda is a function without a def and without a name. The part before the colon is the parameters, and the part after is the single expression whose value is returned automatically:

square = lambda x: x * x
add = lambda a, b: a + b
print(square(4), add(2, 3))
print((lambda x: x + 1)(5))

Output

16 5
6

lambda x: x * x does the same as def square(x): return x * x. You can even call one immediately, as in the last line. A lambda can hold only one expression: no statements, no assignments and no multiple lines. For anything longer, use a normal def (see Python Functions).

One small giveaway that a lambda has no real name:

f = lambda x: x * 2

def g(x):
    return x * 2

print(f.__name__, g.__name__)

Output

<lambda> g

That is why assigning a lambda to a variable (f = lambda ...) is discouraged. If it needs a name, write a def.

Where lambdas earn their keep: sorting and max/min

The most common real use is the key argument of sorted(), max() and min(). The key function says what to compare:

students = [("Asha", 90), ("Ravi", 72), ("Meera", 85)]
print(sorted(students, key=lambda s: s[1]))
print(sorted(students, key=lambda s: s[1], reverse=True)[0])
print(max(students, key=lambda s: s[1]))
words = ["banana", "kiwi", "apple", "fig"]
print(sorted(words, key=lambda w: len(w)))

Output

[('Ravi', 72), ('Meera', 85), ('Asha', 90)]
('Asha', 90)
('Asha', 90)
['fig', 'kiwi', 'apple', 'banana']

Each lambda picks the part of the item to sort by: the score, or the length of the word. For simple lookups, operator.itemgetter does the same and is a little faster and clearer:

from operator import itemgetter

students = [("Asha", 90), ("Ravi", 72), ("Meera", 85)]
print(sorted(students, key=itemgetter(1)))

Output

[('Ravi', 72), ('Meera', 85), ('Asha', 90)]

map(): transform every item

map(function, iterable) calls the function on each item and gives you the results. With two iterables, it passes one item from each:

nums = [1, 2, 3, 4]
print(list(map(lambda x: x * 10, nums)))
print(list(map(str, nums)))
print(list(map(lambda a, b: a + b, [1, 2, 3], [10, 20, 30])))
m = map(str, nums)
print(type(m).__name__)

Output

[10, 20, 30, 40]
['1', '2', '3', '4']
[11, 22, 33]
map

Notice the last line: map returns a map object, a lazy iterator, not a list. Nothing is computed until you loop over it or wrap it in list(). (For how lazy iterators work, see Python Iterators and Generators Explained.)

filter(): keep some items

filter(function, iterable) keeps the items where the function returns a true value. Pass None as the function to keep every truthy item, which is a handy way to drop empty values:

nums = [1, 2, 3, 4, 5, 6]
print(list(filter(lambda x: x % 2 == 0, nums)))
print(list(filter(None, [0, 1, "", "a", None, [], [0]])))
print(list(filter(str.isdigit, ["12", "ab", "7", ""])))

Output

[2, 4, 6]
[1, 'a', [0]]
['12', '7']

The second line dropped 0, the empty string, None and the empty list, but kept [0] because a non-empty list is truthy. The third line passed an existing method, str.isdigit, instead of a lambda, which is always neater when a suitable function already exists.

reduce(): boil a list down to one value

reduce(function, items) takes the first two items, combines them with the function, then combines that result with the third, and so on. It lives in functools because in Python 3 it is not a built-in:

from functools import reduce

nums = [1, 2, 3, 4]
print(reduce(lambda a, b: a + b, nums))
print(reduce(lambda a, b: a * b, nums))
print(reduce(lambda a, b: a + b, nums, 100))
print(reduce(max, [3, 9, 2]))

Output

10
24
110
9

Here is what reduce(lambda a, b: a + b, [1, 2, 3, 4]) does, step by step:

How reduce builds up the answer
Stepa (running result)b (next item)a + b
1123
2336
36410

The third line above passed a starting value, 100, which becomes the first a. For plain adding, though, use sum(), and for the biggest value use max(). Python already has built-ins for the common reductions, so reduce is for the unusual ones.

The three tools chain together. This adds up the squares of the even numbers:

from functools import reduce

nums = [1, 2, 3, 4, 5, 6]
evens = filter(lambda x: x % 2 == 0, nums)
squares = map(lambda x: x * x, evens)
print(reduce(lambda a, b: a + b, squares))

Output

56

map and filter vs comprehensions

Most Python programmers prefer a list comprehension for what map and filter do, because it reads more naturally and needs no lambda. They give identical results:

nums = [1, 2, 3, 4, 5, 6]
print(list(map(lambda x: x * x, nums)) == [x * x for x in nums])
print(list(filter(lambda x: x % 2 == 0, nums)) == [x for x in nums if x % 2 == 0])
print(sum(nums), sum(x * x for x in nums if x % 2 == 0))

Output

True
True
21 56
The same job, two styles
Taskmap / filterComprehension
Transform each itemlist(map(lambda x: x * x, nums))[x * x for x in nums]
Keep some itemslist(filter(lambda x: x % 2 == 0, nums))[x for x in nums if x % 2 == 0]
Bothmap(f, filter(g, nums))[f(x) for x in nums if g(x)]

A good rule: use a comprehension when you would need a lambda, and use map or filter when you already have a function to pass (map(str, nums), filter(str.isdigit, words)). More on comprehensions in Python List Comprehension Explained Simply.

Common mistakes

Mistake 1: forgetting that map and filter are lazy

They return iterators, and an iterator can be used only once. The second pass finds nothing:

nums = [1, 2, 3]
m = map(lambda x: x * 2, nums)
print(list(m))
print(list(m))

Output

[2, 4, 6]
[]

Wrap the result in list() if you need to reuse it.

Mistake 2: lambdas in a loop all see the last value

A lambda looks up its variables when it is called, not when it is created. Three lambdas made in a loop all share the same i, which ends at 2:

funcs = [lambda: i for i in range(3)]
print([f() for f in funcs])
funcs2 = [lambda i=i: i for i in range(3)]
print([f() for f in funcs2])

Output

[2, 2, 2]
[0, 1, 2]

The fix is to freeze the value with a default argument: lambda i=i: i.

Mistake 3: cramming logic into a lambda

If a lambda needs a conditional, a nested call or a comment to be understood, turn it into a named function. Readability matters more than saving two lines.

Mistake 4: using reduce when a built-in exists

sum(nums) beats reduce(lambda a, b: a + b, nums) every time.

Try it yourself

Work out each answer first, then open the solution.

1. Sort ["apple", "fig", "kiwi"] by the last letter of each word.

Show solution
print(sorted(["apple", "fig", "kiwi"], key=lambda w: w[-1]))

Output

['apple', 'fig', 'kiwi']

The last letters are e, g and i, so the order is apple, fig, kiwi.

2. From ["asha", "Ravi", "Amit"] keep the names that start with A, whatever the case.

Show solution
names = ["asha", "Ravi", "Amit"]
print(list(filter(lambda n: n.lower().startswith("a"), names)))

Output

['asha', 'Amit']

3. Use reduce to compute 5 factorial.

Show solution
from functools import reduce

print(reduce(lambda a, b: a * b, range(1, 6)))

Output

120

It multiplies 1 × 2 × 3 × 4 × 5.

4. What does list(map(len, ["a", "bb", "ccc"])) return?

Show answer
print(list(map(len, ["a", "bb", "ccc"])))

Output

[1, 2, 3]

You can pass any function to map, not only a lambda. len is called on each string.

Run these in our free Python compiler.

Frequently asked questions

What is a lambda function in Python?

A lambda is a small anonymous function defined in a single expression with the lambda keyword, for example lambda x: x * 2. It is mainly used for short throwaway functions such as sort keys.

What is the difference between lambda and def?

def creates a named function that can hold many statements. lambda creates an unnamed function limited to one expression. They produce the same kind of function object.

Why does map() return an object instead of a list?

In Python 3 map and filter are lazy: they compute items only when needed, which saves memory. Wrap them in list() to get all the results at once.

Where did reduce go in Python 3?

It moved out of the built-ins into the functools module. Import it with from functools import reduce.

Are map and filter faster than list comprehensions?

Not reliably. The difference is small either way. Choose based on readability, and measure only if speed is a real problem.

When should I avoid lambda?

When the logic is more than a simple expression, when you would assign it to a name, or when a built-in or operator function already does the job.

Run this code in your browser

The free Upskly compiler runs Python with nothing to install. Paste the example, change it and see what happens.

Open Python Compiler

Stuck on a traceback?

AI Assist works inside the Python notebook, so you can ask about an error or a concept without leaving the cell.

Try AI Assist

Test yourself

Timed questions on Decorators and Functional Tools, with an explanation for every answer.

Take the Quiz
Upskly AI Team
Learning made simple
Scroll to Top