In Python, functions are "first-class citizens," meaning they can be passed around just like integers or strings. This flexibility leads us to two powerful concepts: Lambda (Anonymous) functions and Higher-Order Functions.
A Lambda is a small, one-line function that doesn't have a name. You use it when you need a simple piece of logic for a short period and don't want to define a full function using def.
Syntax: lambda arguments : expression
| Type | Example Code | Logic |
|---|---|---|
| Zero Parameters | greet = lambda: "Hello!" |
Returns "Hello!" whenever called. |
| Single Parameter | square = lambda x: x * x |
Takes , returns . |
| Multiple Parameters | add = lambda x, y, z: x + y + z |
Sums three numbers. |
| Default Parameters | power = lambda x, n=2: x ** n |
Squares by default, but can be changed. |
Variable Args (*args) |
sum_all = lambda *args: sum(args) |
Takes any number of inputs. |
A function is "Higher-Order" if it does at least one of the following:
- Takes one or more functions as arguments.
- Returns a function as its result.
Python has built-in HOFs like map(), filter(), and sorted().
numbers = [1, 2, 3, 4, 5, 6]
# 1. filter: Takes a function that returns True/False
evens = list(filter(lambda x: x % 2 == 0, numbers))
# 2. map: Applies a function to every item
doubled = list(map(lambda x: x * 2, numbers))
# 3. sorted: Uses a 'key' function to determine sort order
points = [(1, 2), (3, 1), (5, 10)]
# Sort by the second element of the tuple
sorted_points = sorted(points, key=lambda point: point[1])
print(f"Evens: {evens}")
print(f"Doubled: {doubled}")
print(f"Sorted by Y: {sorted_points}")This is a "Function Factory." The HOF creates and returns a specialized function.
def make_multiplier(n):
# This HOF returns a lambda function
return lambda x: x * n
double = make_multiplier(2)
triple = make_multiplier(3)
print(double(10)) # Output: 20
print(triple(10)) # Output: 30In professional code, you often see these used together to process complex data, like a list of dictionaries (common in Web APIs).
users = [
{"name": "Alice", "age": 25, "role": "admin"},
{"name": "Bob", "age": 17, "role": "user"},
{"name": "Charlie", "age": 30, "role": "user"},
{"name": "David", "age": 15, "role": "admin"},
]
# Task: Get names of all ADULT admins
# 1. Filter for adults (age >= 18) AND role is admin
# 2. Map to extract only the name
logic = lambda u: u['age'] >= 18 and u['role'] == 'admin'
adult_admins = list(map(lambda u: u['name'], filter(logic, users)))
print(f"Adult Admins: {adult_admins}") # Output: ['Alice']Think of it like a Conveyor Belt:
- The List is the raw material on the belt.
- The HOF (
map/filter) is the machine on the belt. - The Lambda is the specific "instruction" you plug into the machine (e.g., "If it's red, throw it away" or "Paint it blue").
- Conciseness: You can do in 1 line what might take 5 lines with a loop.
- Readability: Once you know the syntax,
filter(is_valid, data)is more readable than a longforloop withifstatements. - Functional Programming: It allows for a style of coding that focuses on "what to do" rather than "how to loop."
A Word of Caution: If your lambda gets too complex (e.g., it has nested logic or is very long), it's better to use a regular def function. Code is read more often than it is written!