Lambda expressions and their limits
A lambda is an anonymous function created with an expression: lambda params: expression. It produces an ordinary function object (type function, name '<lambda>') whose body is a single expression that is evaluated and returned implicitly. It supports the full parameter syntax (defaults, *args, keyword-only, **kwargs) and closes over variables like any nested function; the difference from def is purely syntactic. It exists so that a small function can be written inline where one is needed, such as a sort key or a callback.
Limitations compared with def: the body must be one expression, so no statements (assignment, return, raise, try, with, for, while, import, del, assert), though you can use conditional expressions, comprehensions, function calls and a parenthesized walrus. A lambda has no docstring and cannot carry parameter or return annotations, so type checkers must infer its type from context. Its name in tracebacks and profilers is <lambda>, which makes debugging harder than with named functions. It cannot be pickled by name (so it fails with multiprocessing and some serialization), and because it is anonymous it is harder to test and reuse. Python 3 also removed tuple parameter unpacking (PEP 3113), so lambda (a, b): ... from Python 2 is invalid.
How I use them: lambdas are good for short, throwaway callables: sort and min/max keys, a simple callback, a default_factory, or a dispatch-table entry. If the logic needs a name, a comment, multiple steps, or reuse, I use def. PEP 8 discourages assigning a lambda to a name (lint rule E731), since def gives a proper name and traceback and has no downsides. Often a standard-library helper is clearer than a lambda: operator.itemgetter and attrgetter for keys, functools.partial for pre-filling arguments, str methods or builtins like len passed directly.
Common mistakes: closures in loops that capture the variable instead of its value (the [2, 2, 2] example; fix with a default argument or functools.partial), writing lambdas so dense that a nested conditional expression is unreadable, and expecting lambdas to work with multiprocessing or pickle. There is no version-specific change to lambda semantics in recent Python 3 releases.
0-2 years experience
2-5 years experience
5-8 years experience
8+ years experience