Sometimes a function's entire job is one expression — double this, grab that field, test one condition — and it will be used exactly once, right here. Writing a def, naming it, and jumping away to read it is ceremony the moment doesn't need. Python has a word for exactly this: lambda.
What you'll learn
What
A lambda is an anonymous function written as a single expression: lambda x: x * 2. It takes arguments before the colon, evaluates the expression after it, and returns the result — no def, no name, no return keyword.
Why
Lambdas exist to be passed to OTHER functions: sorted(key=...), max(key=...), and — the one that matters most for your future — pandas' df['col'].apply(...). Data code is dense with tiny throwaway transforms, and lambda is their natural syntax.
Where it's used
Sort keys, min/max keys, one-off transforms in .apply() and .map(), and quick predicates handed to filtering utilities.
Where this runs in production
df['price_eur'] = df['price_usd'].apply(lambda p: p * 0.92) — the single most common lambda in data science, run millions of times a day across the industry.
Ranking candidates get sorted by computed keys — sorted(tracks, key=lambda t: t[1], reverse=True) — before heavier scoring models run.
AWS named its serverless product after this concept: a small function invoked on demand. Knowing the Python keyword is table stakes when both appear in one job description.
double = lambda x: x * 2
print(double(5)) # 10
# ...which is exactly equivalent to:
def double(x):
return x * 2Assigning a lambda to a name (top) proves it's a real function — but note the irony: if you're NAMING it, a def was clearer and gives better error messages. PEP 8 explicitly says prefer def for named functions. The legitimate home of a lambda is inline, unnamed, at the point of use.
A def is a recipe card: titled, filed, reusable — worth writing when the dish will be cooked again. A lambda is a sticky note on the counter: 'halve THIS lemon'. Nobody titles a sticky note or files it in the binder; its whole life is one moment of use. Put a recipe on a sticky note and it becomes unreadable — which is precisely what an overgrown lambda is.
sorted(), min(), and max() accept a key argument: a FUNCTION applied to each element, whose result is compared instead of the element itself. sorted(words, key=len) sorts by length; sorted(rows, key=lambda r: r[1]) sorts rows by their second field. This works because functions are values (as you saw with the timed wrapper) — lambda just lets you write the value inline.
products = [('mouse', 25.0), ('laptop', 899.0), ('cable', 8.5)]
by_price = sorted(products, key=lambda p: p[1])
print(by_price[0]) # cheapest first
cheapest = min(products, key=lambda p: p[1])
print(cheapest)The lambda extracts the comparison value from each tuple. Without key=, Python would compare the tuples element-by-element, sorting alphabetically by name — legal, but not what the analysis wanted.
Lambdas can't contain statements (no loops, no assignments, no try), can't have docstrings, and show up in tracebacks as anonymous '<lambda>' — three reasons complex logic doesn't belong in them. The smell test: if your lambda needs parentheses-gymnastics to fit on a line, or you had to read it twice, it's a def in disguise. Extracting it costs four lines and buys a name, a docstring, and a testable unit.
Both produce a function object. Click each side to see what you gain and give up.
Select a type to see its full definition, operations, and data science usage.
Convert one temperature, two ways, to see the equivalence.
Parameters before the colon, expression after, result returned automatically. (Named here only to demonstrate — a def would be the better named version.)
212.0
Your task
A coding-contest leaderboard stores (name, score, minutes) tuples. Using lambdas as keys: (1) sort by score, highest first; (2) find the fastest contestant; (3) sort by score-per-minute efficiency, highest first. Print the results shown.
['mia', 'ada', 'kai'] kai ['kai', 'ada', 'mia']
Write your solution in the editor on the right, then hit Run.
What does (lambda x, y: x * y)(3, 4) evaluate to?
Which is ILLEGAL inside a lambda's body?
words = ['banana', 'Fig', 'apple'] — which call sorts case-insensitively?
What's the right feedback?
orders = [('A-102', 84.0), ('A-101', 210.0), ('A-103', 42.5)]. Using sorted with a lambda key, print the order IDs from most to least expensive. Expected output: ['A-101', 'A-102', 'A-103']
Why does PEP 8 say `f = lambda x: x + 1` should be `def f(x): return x + 1`?
readings = [3.2, -1.5, 4.8, -0.2] — using max with a lambda key, find the reading with the largest ABSOLUTE deviation (use abs), and print it. Expected output: 4.8
What is a lambda and how does it differ from a def?
A lambda is an anonymous function consisting of exactly one expression: lambda x: x * 2 takes arguments before the colon and returns the expression's value with no return keyword. Both lambda and def produce ordinary function objects — the differences are packaging. A def gets a name (which appears in tracebacks and profilers), a docstring, and the full statement language: loops, guards, assignments, try/except. A lambda gets brevity and locality — it's defined at the exact point of use — but is limited to one expression, shows as '<lambda>' in errors, and can't be documented. The intended division of labor: lambda for small throwaway functions passed inline to sorted, min, max, or apply; def for anything named, reused, tested, or multi-step.
Explain how key= works in sorted(), and why it's more efficient than it looks.
key takes a function that's applied to each element once; sorting then compares those computed key values while returning the original elements in the resulting order. sorted(rows, key=lambda r: r[1]) sorts rows by their second field; key=len sorts by length; key=str.lower gives case-insensitive order. The efficiency point worth stating: Python computes each key exactly once and caches it — a 'decorate-sort-undecorate' under the hood — so an expensive key function costs N calls, not N·log N comparisons' worth. Two refinements interviewers like: returning a tuple from the key gives multi-level sorting (key=lambda r: (r[2], r[0]) sorts by third field then first), and when a ready-made function already computes your key — len, str.lower — pass it directly instead of wrapping it in a lambda.
Where do you draw the line between a lambda and extracting a def in data code?
My working rules. Lambda: one expression, one condition at most, used once, inline at the call — the classic df['x'].apply(lambda v: v * 0.92) or a sort key extracting a field. Def the moment ANY of these appear: the logic needs a second conditional or any statement; the same lambda shows up twice (duplication means it deserves a name and a test); the transform embodies a business rule someone will ask about later (rules deserve docstrings); or debugging matters, since a named function turns '<lambda>' in a traceback into something greppable. There's also a middle path people forget: many lambdas wrapping a single call — lambda s: s.strip() — should just pass the underlying function itself, str.strip. The goal isn't avoiding lambdas; it's that each one should be readable at a glance, because at-a-glance is the only advantage it has.
Common Mistakes to Avoid
1) Writing return inside a lambda — SyntaxError; the expression IS the return. 2) Naming lambdas (f = lambda ...) — PEP 8 says def, and tracebacks agree. 3) Nesting conditionals two deep in a lambda — extract a def at the readability cliff. 4) lambda s: len(s) where plain len does the job — don't wrap what already exists. 5) Forgetting key= compares transformed values but returns ORIGINALS (don't re-transform the result). 6) Statements in the body (assignments, loops) — a lambda is one expression, full stop.
Ask the AI Tutor
Try these prompts in the AI Tutor panel: • 'Quiz me on five sorted(key=...) calls — what order comes out?' • 'Show me a lambda that should be a def and refactor it with me.' • 'Explain multi-level sorting with tuple keys.' • 'Preview three pandas .apply() lambdas I'll write in the Data Analysis course.' • 'Interview mode: ask me lambda vs def trade-offs and grade my answer.'
Glossary
lambda — keyword creating an anonymous single-expression function. Anonymous function — a function without a bound name. key= — parameter of sorted/min/max taking a function whose results are compared. reverse=True — sorts descending. Conditional expression — value-if-else, legal in lambdas. Predicate — a function returning True/False. .apply() — the pandas method mapping a function over a column (previewed here). Readability cliff — the point where a lambda's density defeats its brevity. sorted() — built-in returning a NEW sorted list, original untouched.
Recommended Resources
• Docs: 'Lambda Expressions' in the official Python tutorial, and the sorted() how-to guide — the tuple-key trick lives there. • Read: PEP 8's short paragraph on lambda assignment; it settles a real code-review argument in two sentences. • Practice: sort one list of tuples four ways — by each field, then by a computed combination — using only key lambdas. • Next in DSM: lambdas are functions passed as values; Higher-Order Functions makes that idea first-class — map, filter, and functions that build functions.
Recap
✓ lambda params: expression — one expression, auto-returned, no name. ✓ Built to be passed inline: sorted/min/max key=, and pandas .apply() soon. ✓ key= compares transformed values but returns the original elements. ✓ One condition fits; at two, or any statement, extract a def. ✓ Never name a lambda — a def gives tracebacks, docstrings, and tests. ✓ Don't wrap existing functions — pass len, not lambda x: len(x). Next up: Higher-Order Functions. You've been passing functions as values all lesson — now we make that the headline: map, filter, and functions that take (or return) other functions.
Run your code to see the output here.