Python treats functions as first-class objects — they can be stored in variables, passed as arguments, and returned from other functions — and lambda provides a compact syntax for small, throwaway functions.
square = lambda x: x ** 2 # equivalent to: def square(x): return x ** 2
print(square(5)) # 25
numbers = [5, 2, 8, 1, 9]
numbers.sort(key=lambda n: -n) # custom sort key, descending order
print(sorted(numbers, key=abs)) # sort by absolute value
names = ["Rahim", "Ka", "Nadia"]
print(max(names, key=len)) # "Rahim" — longest name, using len as the key function
def apply_twice(func, value): # a function that accepts another function
return func(func(value))
print(apply_twice(lambda x: x + 3, 10)) # 16 — (10+3)+3
A lambda can only contain a single expression (no statements, no multiple lines), which keeps it deliberately limited to small, inline uses — for anything more complex, a regular def function is clearer and should be preferred.
The key= parameter, accepted by sorted(), .sort(), max(), min(), and others, is where lambdas appear constantly in real code: instead of sorting the values themselves, you supply a function that computes what to sort by for each element — key=len sorts by length, key=lambda n: -n sorts descending by negating each value.
Because functions are objects, apply_twice(func, value) above can accept any callable — a lambda, a regular function, or even a class instance with a __call__ method — as its func argument, a pattern that underlies callbacks, strategy patterns, and (as covered in a later lesson) decorators.