Python Lambda
Core Python Functions and Modules

Python Lambda Functions

1Python Lambda: overview

A lambda is a small anonymous function written as a single expression, lambda parameters: expression, that returns the expression's value and is usually passed straight to another function.

GoalBy the end you can write lambda functions, say how they differ from def, use them as key functions for sorted, min and max, store them in a dictionary, avoid the late-binding trap, and decide when a normal def is clearer.

Before this lesson: Python Functions

2Python Lambda: diagram

Python Lambda Functionsdef (named)def total(price, qty): return price * qtylambda (anonymous)lambda price, qty: price * qty# value returned automaticallysame function
A lambda does the same job as a one-line def. It has no name and no return keyword: everything after the colon is a single expression whose value is handed back.

3Python Lambda: explained step by step

A lambda is a small function without a name, written as a single expression. In day-to-day code you meet it in one place above all: as a short throwaway function that you hand to something else, such as sorted() or max(), to tell it how to do its job.

A lambda is a def squeezed into one line

These two forms build the same kind of function object. The lambda is shown inside brackets only so that it can be called on the spot for this demo; normally you would pass it somewhere instead.

Python
def total(price, qty):
    return price * qty

print(total(4, 3))
print((lambda price, qty: price * qty)(4, 3))
print(type(lambda: 0).__name__)

The pattern is lambda parameters: expression. The parameters are written like those of a def, but without brackets. There is no return keyword: whatever the expression evaluates to is what the function gives back.

One expression, no statements

The body of a lambda has to be a single expression: arithmetic, comparisons, function calls, f-strings, even a list comprehension. It cannot contain statements, so no assignment, no return, no for or while block, no try. A lambda also has no place for a docstring. The moment you need a second line, write a normal def.

The everyday job: key functions

sorted(), min() and max() accept a key= function. Python calls it once for every item, and the value it returns decides the order. You get your original items back, just arranged by that value. A lambda is perfect here because the rule is tiny and used once.

Python
students = [("Asha", 82), ("Ben", 91), ("Cara", 77)]
print(sorted(students, key=lambda s: s[1]))
print(max(students, key=lambda s: s[1]))
print(min(students, key=lambda s: s[1])[0])

words = ["banana", "kiwi", "apple", "pear"]
print(sorted(words, key=lambda w: (len(w), w)))

Each s is one whole tuple, so s[1] is the score. Returning a tuple such as (len(w), w) sorts by length first and uses the word itself to break ties. Add reverse=True for descending order.

Choosing inside a lambda

An if statement is not allowed, but the one-line conditional expression, value_if_true if condition else value_if_false, is. It always needs its else.

Python
tasks = [
    {"name": "write report", "urgent": False},
    {"name": "fix login bug", "urgent": True},
    {"name": "book travel", "urgent": False},
]
ordered = sorted(tasks, key=lambda t: (0 if t["urgent"] else 1, t["name"]))
print([t["name"] for t in ordered])

Urgent tasks get the sort value 0, so they come first. The rest are ordered alphabetically.

Functions are values: callbacks and operation tables

In Python a function can be stored in a variable, a list or a dictionary and passed to other functions. Code that receives a function and calls it later is using a callback. A dictionary of lambdas makes a neat lookup table that replaces a long if/elif chain.

Python
operations = {
    "add": lambda a, b: a + b,
    "sub": lambda a, b: a - b,
    "mul": lambda a, b: a * b,
    "div": lambda a, b: a / b if b != 0 else None,
}
for name in ["add", "mul", "div"]:
    print(name, operations[name](12, 4))
print(operations["div"](5, 0))

def apply_twice(func, value):
    return func(func(value))

print(apply_twice(lambda text: text + "!", "hey"))

The late-binding gotcha

A lambda looks up the variables from outside only when it is called, not when it is created. Build several lambdas in a loop and they all see the loop variable's final value:

Python
funcs = []
for n in [1, 2, 3]:
    funcs.append(lambda: n * 10)
print([f() for f in funcs])

funcs = []
for n in [1, 2, 3]:
    funcs.append(lambda n=n: n * 10)
print([f() for f in funcs])

The first list prints [30, 30, 30] because the loop has finished and n is 3 by the time any lambda runs. The fix is n=n: a default value is evaluated immediately, when the lambda is created, so each function keeps its own copy.

Lambda or def?

Use a lambda when the function is short, used once and written exactly where it is needed. Use a def when it is longer than one comfortable line, when you use it in more than one place, or when you want a name. PEP 8, Python's style guide, specifically discourages writing square = lambda x: x * x: it gives you nothing over a def, and the function is less helpful when something goes wrong.

Python
square = lambda x: x * x

def cube(x):
    return x ** 3

print(square.__name__, cube.__name__)

The lambda calls itself <lambda>, so in a traceback you cannot tell which one failed. Also skip the lambda when a built-in already does the job: key=len is clearer than key=lambda w: len(w).

Quick reference: Python Lambda

4Python Lambda: syntax

lambda parameters: expression          # returns the value of the expression

lambda x: x * 2                        # one parameter
lambda a, b: a + b                     # two parameters
lambda: "ready"                        # no parameters
lambda n, base=10: n * base            # default value
lambda n: "even" if n % 2 == 0 else "odd"   # conditional expression (else is required)

sorted(items, key=lambda item: item[1])     # pass it straight to another function
max(items, key=lambda item: item["price"])
lambda n=n: n * 10                          # capture the current value of n in a loop

5Python Lambda: run the example

Press Run (or Ctrl + Enter). The output (step 6) appears directly below the code. Change anything and run it again.

Interactive example
products = [
    {"name": "Keyboard", "price": 49.9, "stock": 12},
    {"name": "Adapter", "price": 19.5, "stock": 0},
    {"name": "Monitor", "price": 189.0, "stock": 4},
    {"name": "Cable", "price": 5.0, "stock": 60},
]

by_price = sorted(products, key=lambda p: p["price"])
print([p["name"] for p in by_price])

cheapest = min(products, key=lambda p: p["price"])
print("Cheapest:", cheapest["name"])

in_stock_first = sorted(products, key=lambda p: (p["stock"] == 0, p["name"]))
print([p["name"] for p in in_stock_first])
Expected output['Cable', 'Adapter', 'Keyboard', 'Monitor']
Cheapest: Cable
['Cable', 'Keyboard', 'Monitor', 'Adapter']

7Python Lambda: how the example works

Hover or tap a step to highlight its lines in the example above.

  1. Line 1-6A list of four product dictionaries. Each one has a name, a price and a stock level.
  2. Line 8sorted() calls the lambda once for each product. The lambda returns the product's price, and the products are arranged by those numbers. The result is a new list of the same dictionaries; products itself is unchanged.
  3. Line 9A list comprehension picks out just the names, so the output is easy to read: cheapest first.
  4. Line 11min() accepts the same kind of key. It returns the whole product dictionary with the lowest price, not the price itself.
  5. Line 12Since cheapest is the dictionary for the cable, cheapest["name"] is "Cable".
  6. Line 14The key returns a tuple. p["stock"] == 0 is False for products that are in stock and True for the adapter. False sorts before True, so products in stock come first, and the name breaks ties.
  7. Line 15The adapter is out of stock and moves to the end, even though its name would otherwise sort first.

8Python Lambda: common mistakes

Using return inside a lambda

✗ Wrong

prices = [30, 10, 20]
print(sorted(prices, key=lambda p: return -p))
SyntaxError: invalid syntax

✓ Right

prices = [30, 10, 20]
print(sorted(prices, key=lambda p: -p))

A lambda body is a single expression and its value is returned automatically. Remove the return keyword. If you need statements, use a def.

A conditional expression without else

✗ Wrong

sizes = list(map(lambda n: "big" if n > 100, [50, 150]))
print(sizes)
SyntaxError: expected 'else' after 'if' expression

✓ Right

sizes = list(map(lambda n: "big" if n > 100 else "small", [50, 150]))
print(sizes)

Inside a lambda, if is a conditional expression and it must produce a value in every case. Add an else branch.

Giving a key lambda two parameters

✗ Wrong

students = [("Asha", 82), ("Ben", 91), ("Cara", 77)]
print(sorted(students, key=lambda name, score: score))
TypeError: <lambda>() missing 1 required positional argument: 'score'

✓ Right

students = [("Asha", 82), ("Ben", 91), ("Cara", 77)]
print(sorted(students, key=lambda s: s[1]))

key calls the function with ONE argument: the whole item. Here that is a tuple, so take one parameter and index into it.

Forgetting to call the lambda you stored

✗ Wrong

operations = {"add": lambda a, b: a + b}
print("Sum:", operations["add"])
No error, but it prints Sum: <function <lambda> at 0x7f...> instead of 5

✓ Right

operations = {"add": lambda a, b: a + b}
print("Sum:", operations["add"](2, 3))

operations["add"] is the function itself. To run it, add brackets with the arguments, just like a normal function call.

Lambdas created in a loop all use the last value

✗ Wrong

greeters = []
for name in ["Asha", "Ben", "Cara"]:
    greeters.append(lambda: f"Hello, {name}!")
print(greeters[0]())
No error, but it prints Hello, Cara! instead of Hello, Asha!

✓ Right

greeters = []
for name in ["Asha", "Ben", "Cara"]:
    greeters.append(lambda name=name: f"Hello, {name}!")
print(greeters[0]())

The lambda reads name when it is called, after the loop has ended and name is "Cara". Capture the current value with a default argument, name=name.

9Python Lambda: exercises

Write your answer, then press Check. The checks run in your browser.

1. Sort names by their last letter

Write code Easy

Write a function sort_by_last(names) that returns a new list of the names sorted by their last letter. Use sorted() with a lambda as the key. Names that share a last letter keep their original order.

Then print the result for ["Asha", "Ben", "Cara", "Dan"].

Your code
def sort_by_last(names):
    # return a new list sorted by the last letter of each name
    pass

print(sort_by_last(["Asha", "Ben", "Cara", "Dan"]))

2. Predict the operation table

Predict the output Medium

A dictionary stores three lambdas and the program calls them by name. Type exactly what it prints, then press Check.

Read this code
rules = {
    "double": lambda n: n * 2,
    "negate": lambda n: -n,
    "label": lambda n: "even" if n % 2 == 0 else "odd",
}
for name in ["double", "negate", "label"]:
    print(name, rules[name](7))
print(rules["label"](rules["double"](3)))

2 more exercises → 6 more examples

Finished this lesson?
Progress is saved in this browser — create a free account to keep it across devices.

Questions learners ask

What is a lambda function in Python and when should I use it?

A lambda is a small anonymous function written as lambda parameters: expression. Use one when you need a short function exactly once, usually as the key= of sorted(), min() or max(), or as a callback. If the function is longer, reused, or deserves a name, write a normal def.

Can a lambda have multiple statements or lines?

No. A lambda body is one expression, so assignments, return, loops and try blocks are not allowed. You can use a conditional expression (a if condition else b) and wrap a long expression in brackets over several lines, but it is still a single expression. For anything more, use def.

Is a lambda faster than a normal function?

No. A lambda and a def function are the same kind of object and run at the same speed. The only differences are the syntax and the name: a lambda is always called <lambda>, which makes tracebacks harder to read. Choose between them for clarity, not performance.

Further reading

10Next lesson

Up nextPython RecursionRecursion is when a function solves a problem by calling itself on a smaller version of that problem, stopping at a bas…

Related:
Python SortingPython FunctionsPython ClosuresPython map, filter and reduce

← Python *args and **kwargs · All Functions and Modules lessons · Practise in the IDE