Lambda + map/filter
Sometimes you need a function for exactly one moment — a tiny throwaway check inside a sort, a quick transformation of a list. Writing a full def for three characters of logic feels heavy. Enter lambda — and its partners map and filter.
lambda — the anonymous function
A lambda is a function with no name, written in one line:
double = lambda x: x * 2
print(double(5)) # 10
The anatomy: lambda keyword, parameters, colon, one expression (no statements, no if/for blocks — the expression’s value is returned automatically).
Compare with def — same behavior, different weight:
def double(x):
return x * 2
Where lambdas actually belong: inside other functions
Assigning a lambda to a name (double = lambda...) is discouraged — a def is clearer for named functions. Lambdas shine as throwaway arguments:
names = ["Diya", "Aarav", "Kabir"]
# sort by length of name
print(sorted(names, key=lambda name: len(name)))
# ['Diya', 'Kabir', 'Aarav']
# sort pairs by score (you met this in the looping lesson!)
scores = [("Aarav", 92), ("Diya", 95), ("Kabir", 78)]
print(sorted(scores, key=lambda pair: pair[1], reverse=True))
# [('Diya', 95), ('Aarav', 92), ('Kabir', 78)]
sorted needs a function that extracts the sort value — the lambda provides it inline, used once, gone. This key=lambda ... pattern is the single most common lambda in real code.
map — transform every item
map(function, iterable) applies the function to every item:
numbers = [1, 2, 3, 4]
doubled = list(map(lambda x: x * 2, numbers))
print(doubled) # [2, 4, 6, 8]
# convert a list of strings to ints
raw = ["10", "20", "30"]
values = list(map(int, raw))
print(values) # [10, 20, 30]
Note the list(...) wrapper — map produces a lazy map-object; list() collects it into a real list you can print.
filter — keep only the matches
filter(condition_function, iterable) keeps items where the function returns True:
numbers = [5, 12, 8, 3, 19, 22]
evens = list(filter(lambda x: x % 2 == 0, numbers))
print(evens) # [12, 8, 22]
map + filter together
numbers = [1, 2, 3, 4, 5, 6]
# evens, doubled
result = list(map(lambda x: x * 2, filter(lambda x: x % 2 == 0, numbers)))
print(result) # [4, 8, 12]
It works… but read that line again. Two nested lambdas is where readability starts dying.
The honest truth: comprehensions usually win
The same result, Pythonically:
result = [x * 2 for x in numbers if x % 2 == 0]
print(result) # [4, 8, 12]
One line, no lambdas, reads left to right. Modern Python style prefers comprehensions for transform/filter work — they’re the subject of Module 10. So why learn map/filter now?
key=lambdain sorted/max/min is irreplaceable and everywhere- Reading other people’s code — map/filter appear constantly in tutorials and real projects
- The concepts (transform every item / keep matching items) are universal — comprehensions are just their prettier syntax
Rule of thumb: sorted’s key → lambda; transform/filter → comprehension (soon); quick one-off logic → lambda.
Common Errors & Fixes
SyntaxErroron multi-line lambda bodies — lambdas are one expression only. If you need statements, use def.<map object at 0x...>printed — you forgotlist()around the map.- Lambda assigned to a name (
f = lambda x: x*2) — legal but flagged by style guides; use def for named functions.
✅ Checkpoint
- Write a lambda that returns a string uppercased. (lambda s: s.upper())
- Sort
wordsby length using sorted + lambda. (sorted(words, key=lambda w: len(w))) - What does
list(map(int, ["5", "6"]))give? ([5, 6]) - What usually replaces map/filter chains in modern Python? (Comprehensions — Module 10)
Module 7 checkpoint reached — functions from every angle: definition, defaults, flexibility, scope, and one-liners.
Next module: Errors & Files — handling failure gracefully and making data persist.