What are lambda functions, and when should you avoid them?

4 minbeginnerfunctionslambda

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.
  • def supports 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 def can'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.