lambda

lambda builds a function from a single expression, whose value is returned. No statements, no name, no annotations — and the same late-binding rules as any closure.

FunctionsPython 3 (all)Live demo
lambda
lambda params: expression
as a key function
sorted(items, key=lambda x: x[1])
with defaults
lambda a, b=2, *args: a + b
Use for
key= for sorted / min / max, small callbacks, one-line map/filter functions
Result
a function object (its __name__ is "<lambda>")
Pairs with
sorted(), min(), max(), map(), filter(), conditional expressions
Watch out
names in the body are looked up when it is CALLED — loop variables are not captured by value

Demo

Live evaluation
Sort by absolute value. The lambda computes the sort key; the original numbers are what come back, and ties keep their order.
Try:
Inputs
numslistcomma-separated
Code
sorted([3, -1, -5, 2], key=lambda n: abs(n))
Result
[-1, 2, 3, -5]

The key= tab never changes the numbers — abs() only decides the order, and sorted() is stable, so -2 stays ahead of 2. The late binding tab is the whole story of lambdas in loops: the body reads x at call time, unless you copy the value into a default argument.

Syntax slots

NameTypeRequiredDescription
paramsparameter listnoSame rules as def: defaults, *args, **kwargs, / and * markers. Can be empty: lambda: 0.
expressionexpressionyesEvaluated on every call; its value is returned. Only an expression — no return, assignment statements, loops or try.

Common patterns

Sort by a field
The classic use: tell sorted what to compare.
people.sort(key=lambda p: (p.last, p.first))
Pick the best item
max/min with key return the item, not the key.
best = max(scores.items(), key=lambda kv: kv[1])
Capture a loop value
A default argument freezes the current value.
buttons = [make_button(text=t, on_click=lambda t=t: select(t))
           for t in labels]
operator module instead
itemgetter / attrgetter are faster and pickleable replacements for simple lambdas.
from operator import itemgetter
rows.sort(key=itemgetter(1))

Examples

1. A lambda is a function
square = lambda x: x * x square(5)
Returns
25
2. Sort strings by length
sorted(['pear', 'fig', 'apple'], key=lambda w: len(w))
Returns
['fig', 'pear', 'apple']
3. Sort pairs by the second item
pairs = [('a', 3), ('b', 1)] sorted(pairs, key=lambda p: p[1])
Returns
[('b', 1), ('a', 3)]
4. Defaults work like in def
(lambda a, b=2: a + b)(3)
Returns
5
5. Conditional expression inside
sign = lambda n: 'neg' if n < 0 else 'non-neg' sign(-4)
Returns
'neg'
6. max with a key
max({'a': 3, 'b': 7}.items(), key=lambda kv: kv[1])
Returns
('b', 7)
7. Its name is <lambda>
f = lambda: 0 f.__name__
Returns
'<lambda>'
8. No statements allowed
compile('f = lambda x: return x', '<demo>', 'exec')
Returns
SyntaxError: invalid syntax

Pitfalls

1. Lambdas created in a loop all see the last value
The body looks i up when called, after the loop has finished. Bind the current value with a default argument.
late binding
funcs = [lambda: i for i in range(3)]
[f() for f in funcs]
[2, 2, 2]
default argument
funcs = [lambda i=i: i for i in range(3)]
[f() for f in funcs]
[0, 1, 2]
2. A comma after the body makes a tuple
The comma is not part of the lambda body: f = lambda x: x, 2 is a tuple of (lambda, 2), not a lambda returning a tuple.
bare comma
f = lambda x: x, 2
f(1)
TypeError: 'tuple' object is not callable
parenthesise
f = lambda x: (x, 2)
f(1)
(1, 2)
3. Naming a lambda instead of using def
A lambda bound to a name gives worse tracebacks and repr — PEP 8 recommends def for anything you name.
named lambda
double = lambda x: x * 2
double.__name__
'<lambda>'
def
def double(x):
    return x * 2
double.__name__
'double'

When to use

Use it
  • key= arguments of sorted(), list.sort(), min(), max(), itertools.groupby()
  • Short callbacks passed straight to another function
  • Default factories such as defaultdict(lambda: [0, 0])
Reach for something else
  • Anything you would assign to a name → def (a real name, a docstring)
  • Logic that needs statements, several lines or error handling → def
  • map(lambda x: x * 2, xs) → a comprehension [x * 2 for x in xs] usually reads better

Notes

CPython impl
A lambda compiles to the same kind of code object as a def; only __name__ / __qualname__ ("<lambda>") differ
Scope
The body is a new scope: free names are looked up when the lambda runs, exactly like a nested def
Parsing
lambda binds more loosely than every operator except :=, so 'lambda: x = 1' parses as assigning to the lambda (SyntaxError: cannot assign to lambda)

FAQ

A small anonymous function written as an expression: lambda x: x * 2 is equivalent to a def that returns x * 2. It can take any parameters a def can, but its body is a single expression whose value is returned.