Python lambdas, explained
A lambda is a small anonymous function written inline. It's not more powerful than a normal
function — it's more limited — but it shines in one place: passing a short throwaway
function as an argument, especially as a key. This guide covers what lambdas can and can't
do, and the higher-order functions that consume them.
What a lambda is
lambda builds a function object from a single expression. These two are equivalent:
square = lambda x: x * x
def square(x): return x * x
square(5) # 25
The syntax is lambda args: expression. The expression's value is returned automatically —
there's no return keyword.
The limitations of lambdas
A lambda is restricted to a single expression. It cannot contain statements —
no assignments, no if/for blocks, no try, no multiple lines:
lambda x: x * 2 # fine
lambda x: x if x > 0 else -x # fine (conditional EXPRESSION is allowed)
lambda x: return x # SyntaxError — statements not allowed
lambda vs def
Because a lambda's body is one expression, use def for anything with real logic. Critically,
don't assign a lambda to a name — that's exactly what def is for, and def gives the
function a proper __name__ for tracebacks:
# Un-Pythonic — a named lambda:
f = lambda x: x + 1
# Preferred:
def f(x):
return x + 1
Use a lambda only when the function is anonymous and passed inline.
Higher-order functions
A higher-order function is one that takes a function as an argument or returns one.
map, filter, sorted, and decorators are all higher-order:
def apply_twice(fn, x):
return fn(fn(x))
apply_twice(lambda n: n + 3, 10) # 16
This is possible because functions are first-class (next section).
The key argument
The most useful place for a lambda is the key parameter of sorted, max, and min.
key is a function applied to each element to decide the comparison value:
words = ["banana", "kiwi", "apple"]
sorted(words, key=len) # ['kiwi', 'apple', 'banana']
max(words, key=len) # 'banana'
people = [("Ada", 36), ("Alan", 41)]
sorted(people, key=lambda p: p[1]) # sort by age
sorted(people, key=lambda p: p[1], reverse=True)
For attribute or item access, operator.itemgetter/attrgetter are faster and clearer than
a lambda:
from operator import itemgetter
sorted(people, key=itemgetter(1)) # same as the lambda above
Functions are first-class objects
"First-class" means functions are ordinary objects: you can assign them to variables, store them in lists or dicts, pass them as arguments, and return them. This is what makes lambdas, higher-order functions, and decorators possible:
ops = {"+": lambda a, b: a + b, "-": lambda a, b: a - b}
ops["+"](2, 3) # 5 — a function stored in a dict, called by key
def greet():
return "hi"
g = greet # assign the function object itself (no parentheses)
g() # 'hi'
Note greet is the function object; greet() calls it. Passing greet (no parens) hands
the function around for someone else to call.
Recap
A lambda is an anonymous, single-expression function — handy inline, but it can't hold
statements, so use def for anything substantial and never bind a lambda to a name. A
higher-order function takes or returns functions, the prime example being the key
argument to sorted/max/min (or operator.itemgetter for plain field access). All of
this rests on functions being first-class objects you can pass, store, and return like
any other value.