PythonBeginner 12 min Lesson 14 of 30

Day 14 — Lambda, map and filter

Small anonymous functions and where they genuinely help: sorting by a field, mapping values, and why comprehensions usually read better.

Python · Lesson 14 of 30
0/30 done(0%)

What is it? #

A lambda is a small function written inline, without a name. lambda x: x * 2 is the same idea as a one-line def, just expressed where you need it.

Lambdas can only hold a single expression. No statements, no multiple lines. That restriction is deliberate — anything bigger deserves a real function with a name.

map() applies a function to every item, and filter() keeps the items where a function returns true. Both return lazy iterators, so you usually wrap them in list().

In modern Python, the strongest use for a lambda is the key argument of sorted, max, min and groupby. For plain mapping and filtering, a comprehension is usually clearer.

Think of it like this #

A lambda is a sticky note instruction. You would not print a formal document to say "sort these by date" — you scribble it on a note and hand it over with the pile. But if the instruction runs to three paragraphs, it belongs in a proper document with a title.

Simple example #

You have a list of employee dictionaries and need them sorted by salary, then by name. You also want the highest earner and a quick list of names in uppercase.

Code #

PYTHON
staff = [
    {"name": "ravi", "salary": 92000, "dept": "eng"},
    {"name": "anita", "salary": 120000, "dept": "eng"},
    {"name": "sam", "salary": 78000, "dept": "sales"},
]

# Sorting by a field — the best use of lambda
by_salary = sorted(staff, key=lambda p: p["salary"], reverse=True)
print([p["name"] for p in by_salary])          # ['anita', 'ravi', 'sam']

# Sorting by two fields
by_dept_then_pay = sorted(staff, key=lambda p: (p["dept"], -p["salary"]))
print([p["name"] for p in by_dept_then_pay])   # ['anita', 'ravi', 'sam']

top = max(staff, key=lambda p: p["salary"])
print(top["name"])                              # anita

# map and filter
names = list(map(lambda p: p["name"].title(), staff))
print(names)                                    # ['Ravi', 'Anita', 'Sam']

eng = list(filter(lambda p: p["dept"] == "eng", staff))
print(len(eng))                                 # 2

# The comprehension versions — usually clearer
names = [p["name"].title() for p in staff]
eng = [p for p in staff if p["dept"] == "eng"]

# operator.itemgetter avoids the lambda entirely
from operator import itemgetter
by_salary = sorted(staff, key=itemgetter("salary"))

How it works #

sorted(staff, key=lambda p: p["salary"]) calls the lambda once per item to work out what to sort on. The lambda receives one employee and returns the value to compare. reverse=True flips the order.

The two-field sort returns a tuple: (p["dept"], -p["salary"]). Python compares tuples element by element, so it sorts by department first and then by salary. The minus sign reverses only the salary part, which is a neat trick you cannot get from reverse=True alone.

max(staff, key=...) uses the same idea — it finds the item whose key value is largest and returns the whole item, not just the key.

map(lambda p: ..., staff) applies the lambda to each item. It returns an iterator, so list() is needed to see the results. filter works the same way but keeps items where the function returns true.

The comprehension versions below do exactly the same work with fewer moving parts and no list() wrapper. That is why most Python style guides nudge you towards comprehensions for mapping and filtering, while leaving lambdas for key arguments.

itemgetter("salary") is a ready-made function that pulls a key out of a dictionary. It is slightly faster than a lambda and reads well when sorting by a plain field.

Real-world use #

Sorting by a computed key is the everyday use: orders by date, products by discount percentage, log entries by severity then timestamp. Any list shown to a user has a sort key behind it.

map and filter appear more often in codebases influenced by functional languages, and in code that processes streams lazily. Knowing how to read them matters even if you write comprehensions yourself.

Lambdas also show up as small callbacks: a default factory, a key function passed into a library, a simple transformation handed to a data frame operation. The rule of thumb holds — if the lambda needs a comment, promote it to a named function.

Common mistakes #

  • Assigning a lambda to a name (f = lambda x: ...). Just use def — you get a proper name in tracebacks.
  • Writing a long, nested lambda. If it has conditionals stacked inside, it belongs in a function.
  • Forgetting that map and filter return iterators, then being surprised that printing shows an object address.
  • Using sorted(x, key=lambda i: i) when plain sorted(x) does the same thing.
  • Building a lambda inside a loop that captures the loop variable, then wondering why every callback uses the last value.

Practice #

Given a list of product dictionaries with name, price and rating, sort them by rating descending and price ascending in a single sorted call. Find the cheapest product with max/min and a key function. Then rewrite one map call as a comprehension and compare readability.

Quick quiz

  1. 1. What can a lambda contain?

  2. 2. What does the `key` argument of `sorted` do?

  3. 3. How do you sort by department ascending and salary descending in one call?

  4. 4. What does `map()` return in Python 3?

  5. 5. Why prefer `def` over assigning a lambda to a variable?

Summary

  • A lambda is a one-expression function written where it is used.
  • Its best use is the `key` argument of sorted, max and min.
  • Tuple keys let you sort by several fields at once.
  • map and filter return lazy iterators; comprehensions usually read better.
  • If a lambda needs explaining, turn it into a named function.