What are lambda functions, and when should you avoid them?
Quick Answer
A `lambda` is an anonymous, single-expression function — `lambda x: x * 2` is equivalent to a `def` with one `return` statement, but has no name, no statements (only one expression), and no docstring. Use lambdas for short, throwaway callbacks (`sorted(key=lambda x: x.name)`); avoid them for anything that needs a name for debugging/tracebacks, has multiple logical steps, or would benefit from a docstring — PEP 8 explicitly recommends `def` over binding a lambda to a name.
Detailed Answer
What a lambda is
square = lambda x: x * x
# equivalent to:
def square(x):
return x * x
A lambda is restricted to a single expression — no statements (no
if/for blocks, no multiple lines, no assignments other than the
walrus operator inside the expression). Its return value is always that
one expression's result.
Good uses: short, inline, throwaway callbacks
people.sort(key=lambda p: p.last_name)
sorted(words, key=lambda w: (-len(w), w))
list(filter(lambda x: x % 2 == 0, numbers))
button.on_click(lambda: print("clicked"))
These are idiomatic — the lambda exists only to describe "how to sort/ filter this," used once, right where it's needed, and naming it separately would add indirection without adding clarity.
Why PEP 8 discourages binding a lambda to a name
# PEP 8: don't do this
f = lambda x: x * 2
# do this instead
def f(x):
return x * 2
Once you're naming the function anyway, def is strictly better:
- Tracebacks show the real name. A named lambda's
__name__is literally"<lambda>", which makes stack traces harder to read. defsupports a docstring, statements, multiple lines, and default values with the same clarity as any other function.- No expressiveness advantage — a bound lambda can't do anything a
one-line
defcan't, so there's no upside to the restriction.
Lambdas can't contain statements — a common trip-up
lambda x: print(x); return x # SyntaxError -- can't have multiple statements
lambda x: x if x > 0 else -x # OK -- this is a conditional EXPRESSION, not a statement
A conditional expression (a if cond else b) is fine inside a lambda;
actual statements (if, for, try, assignment, return) are not.
Interview-ready summary: Lambdas are single-expression anonymous
functions, ideal for short inline callbacks like sort keys or simple
filters. The moment a lambda is complex enough to need a name, multiple
steps, or a docstring, write a regular def instead — PEP 8 treats
name = lambda: ... as an anti-pattern.