Know some Python? Write your own interactive tutorial, with runnable examples and exercises, and share it with a link. Write and share your own tutorial.

Start writing

Learn Python / Lambda, map and filter

Lambda, map and filter

In Python, functions are values, just like numbers and strings. You can store them in variables, put them in lists and pass them to other functions. This lesson shows how, and introduces lambda, a quick way to write tiny functions on the spot.

Functions are values

A function name without () refers to the function itself, without calling it:

def shout(text):
    return text.upper() + "!"

# no parentheses: not calling it
yell = shout
print(yell("hello"))
print(type(shout))
Output

yell = shout doesn't run anything. It gives the same function a second name, so yell("hello") and shout("hello") do exactly the same thing. Compare result = shout("hello"), which calls the function and stores its return value, "HELLO!".

So you can pass a function into another function:

def apply_twice(func, value):
    return func(func(value))

def add_three(n):
    return n + 3

print(apply_twice(add_three, 10))
Output

add_three is passed without parentheses, so apply_twice receives the function itself and calls it as func. func(func(10)) becomes add_three(add_three(10)), which is add_three(13), which is 16.

Lambda functions

A lambda is a small function written in a single expression, without def or a name:

lambda parameters: expression

These two do the same thing:

def square(n):
    return n * n

square_lambda = lambda n: n * n

print(square(6))
print(square_lambda(6))
Output

Reading lambda n: n * n piece by piece:

Part Meaning
lambda "here comes a small function"
n its parameter (several are separated by commas; there are no parentheses)
: separates the parameters from the result
n * n the value it returns. There's no return keyword; the expression is the return value

A lambda can take several parameters, and its expression is returned automatically:

add = lambda a, b: a + b
full_name = lambda first, last: f"{first} {last}".title()

print(add(2, 3))
print(full_name("ada", "lovelace"))
Output

Lambdas are limited to one expression: no loops, no assignments, no multiple statements. Their real use is as short throwaway functions passed to other functions. Storing one in a variable, as above, is just for demonstration. If a function deserves a name, write it with def, which also gives it a docstring and clearer error messages.

Sorting with a key

sorted(), min() and max() accept a key function. It's called on each item, and the results decide the order. This is where lambdas are used most:

words = ["banana", "Apple", "cherry", "date"]

print(sorted(words))
print(sorted(words, key=str.lower))
print(sorted(words, key=len))
print(sorted(words, key=lambda w: w[-1]))
Output
key= Python compares Result
(none) the words themselves; capitals come first Apple, banana, cherry, date
str.lower the lowercase versions Apple, banana, cherry, date
len the lengths: 6, 5, 6, 4 date, Apple, banana, cherry
lambda w: w[-1] the last letters banana, Apple, date, cherry

The key is only used for comparing. The result still contains the original items, unchanged; sorted(words, key=len) gives words, not numbers. When two items have the same key (like banana and cherry, both length 6), they keep their original order. Pass the function itself, without (): key=len, not key=len().

It's especially handy for lists of tuples or dictionaries:

students = [("Mia", 88), ("Leo", 95), ("Ava", 72)]

by_score = sorted(students, key=lambda s: s[1], reverse=True)
print(by_score)

best = max(students, key=lambda s: s[1])
print("Top student:", best[0])
Output

Each student is a tuple (name, score), so s[1] is the score. key=lambda s: s[1] means "compare the students by their score". max() with a key gives back the whole tuple, ("Leo", 95), which is why the last line uses best[0] for the name.

products = [
    {"name": "Laptop", "price": 999},
    {"name": "Mouse", "price": 25},
    {"name": "Monitor", "price": 249},
]

cheapest_first = sorted(products, key=lambda p: p["price"])
for p in cheapest_first:
    print(p["name"], p["price"])
Output

map(): apply a function to every item

map(function, iterable) calls the function on each item. It returns a lazy map object, so wrap it in list() to see the results:

numbers = [1, 2, 3, 4]

doubled = map(lambda n: n * 2, numbers)
print(doubled)
print(list(doubled))

print(list(map(str.upper, ["a", "b", "c"])))

# convert strings to ints
print(list(map(int, ["10", "20", "30"])))
Output

"Lazy" means map() doesn't do any work until you ask for the results, which is why printing doubled shows only <map object at ...>. A map object can be used once: after list(doubled) has gone through it, a second list(doubled) gives []. If you need the results more than once, store the list.

A common trick reads several numbers from one line of input:

line = "3 8 15 4"
numbers = list(map(int, line.split()))
print(numbers, sum(numbers))
Output

filter(): keep the items that pass a test

filter(function, iterable) keeps the items for which the function returns something truthy:

numbers = [5, 12, 7, 20, 3, 18]

big = filter(lambda n: n > 10, numbers)
print(list(big))

# None: keep only truthy items
words = ["", "hello", "", "world"]
print(list(filter(None, words)))
Output

The function is called on each item: 5 > 10 is False, so 5 is dropped; 12 > 10 is True, so 12 is kept. Like map(), filter() is lazy, so it's wrapped in list(). Passing None instead of a function keeps the items that are truthy by themselves, which here removes the empty strings.

Function Gives back Length of the result
map(f, items) f(item) for every item the same as items
filter(f, items) the items where f(item) is truthy, unchanged the same or shorter

Comprehensions are often clearer

Anything map and filter do, a list comprehension can do too, and many Python programmers find the comprehension easier to read:

numbers = [5, 12, 7, 20, 3, 18]

print(list(map(lambda n: n * 2, numbers)))
print([n * 2 for n in numbers])

print(list(filter(lambda n: n > 10, numbers)))
print([n for n in numbers if n > 10])
Output

A good rule of thumb:

  • Use map when you already have a named function: map(int, parts).
  • Use a comprehension when you'd need a lambda.
  • Use a lambda mostly for key= arguments.
Going deeper: any() and all() optional

Two more built-ins answer yes-or-no questions about a whole collection:

  • any(items) is True if at least one item is truthy.
  • all(items) is True if every item is truthy.

They pair nicely with a comprehension that turns each item into True or False:

scores = [72, 85, 90, 66]

# did anyone get 90 or more?
print(any(s >= 90 for s in scores))

# did everyone pass?
print(all(s >= 50 for s in scores))
print(all(s >= 70 for s in scores))
Output

Notice there are no square brackets inside any() and all(). That's a generator expression, which you'll meet in Iterators and Generators. Writing any([s >= 90 for s in scores]) with brackets works too.

Both stop as soon as they know the answer, so any() stops at the first True. On an empty collection, any([]) is False and all([]) is True, because no item breaks the rule.

Exercises

Exercise 1: Sort by length

Sort the names from shortest to longest using sorted() with a key. It should print ['Al', 'Mia', 'Grace', 'Alexander'].

names = ["Grace", "Al", "Alexander", "Mia"]
Output

Exercise 2: Most expensive item

Use max() with a lambda to find the most expensive item, and print its name: Laptop.

items = [("Pen", 1.5), ("Laptop", 899.0), ("Book", 12.99)]
Output

Exercise 3: map and filter

Use filter to keep the odd numbers, then map to square them, and print the list: [1, 9, 25, 49, 81].

numbers = list(range(1, 11))
Output

Exercise 4: Rewrite as a comprehension

Rewrite the map/filter line as a single list comprehension that gives the same result.

words = ["python", "is", "fun", "and", "powerful"]

result = list(map(str.upper, filter(lambda w: len(w) > 3, words)))
print(result)
Output

Functions that take functions at a glance

A quick reference for later. The examples use words = ["kiwi", "fig", "banana"] and nums = [3, -5, 2].

Tool What it does Example Result
lambda args: expr A small one-line function (lambda x: x * 2)(5) 10
sorted(items, key=f) Sorts by f(item) instead of the item itself sorted(words, key=len) ['fig', 'kiwi', 'banana']
sorted(items, key=f, reverse=True) The same, largest first sorted(words, key=len, reverse=True) ['banana', 'kiwi', 'fig']
items.sort(key=f) Like sorted(), but sorts the list in place words.sort(key=len) words becomes ['fig', 'kiwi', 'banana']
min(items, key=f) The item with the smallest f(item) min(nums, key=abs) 2
max(items, key=f) The item with the largest f(item) max(words, key=len) 'banana'
map(f, items) Applies f to every item list(map(abs, nums)) [3, 5, 2]
filter(f, items) Keeps the items where f(item) is truthy list(filter(lambda n: n > 0, nums)) [3, 2]
filter(None, items) Keeps only the truthy items list(filter(None, [0, 1, "", "a"])) [1, 'a']
any(...) Is at least one item truthy? any(n < 0 for n in nums) True
all(...) Is every item truthy? all(n < 0 for n in nums) False

Summary

  • Functions are values: you can store them and pass them to other functions.
  • lambda params: expression makes a small one-expression function.
  • sorted, min and max take a key= function that decides the order.
  • map(func, items) transforms every item, and filter(func, items) keeps the items that pass.
  • Wrap map and filter in list() to see the results.
  • When you'd need a lambda, a list comprehension is often clearer.

Share this tutorial

Know something worth teaching? Write your own tutorial with runnable examples and share it.