Python FAQ: Top Questions
14. What is a `lambda` function in Python? When is it used?
In Python, a **`lambda` function** (also known as an anonymous function) is a small, single-expression function that doesn't have a formal name. It is defined using the `lambda` keyword. Lambda functions are typically used for short, simple operations where defining a full `def` function would be overly verbose or unnecessary.
Syntax:
lambda arguments: expression
- `lambda`: The keyword used to define an anonymous function.
- `arguments`: A comma-separated list of arguments the lambda function can take. Similar to regular functions, these can include positional, default, and keyword-only arguments.
- `expression`: A single expression. The value of this expression is implicitly returned by the lambda function. It cannot contain multiple statements or complex constructs like loops, `if/else` statements (though it can use a conditional expression, e.g., `x if condition else y`), `try/except` blocks, or assignments.
Characteristics and Limitations:
- **Anonymous:** They don't have a name, which means they can't be directly referenced later unless assigned to a variable (though this defeats the purpose of "anonymous").
- **Single Expression:** Limited to a single expression, which is implicitly returned. This is the primary constraint.
- **No Docstrings:** They cannot have docstrings.
- **No Complex Logic:** Cannot contain statements (like `return`, `for`, `while`, `if` statements, `import`, etc.), only expressions.
- **Lexical Scope:** Like regular functions, lambdas can access variables from their enclosing scope (closures).
When to Use `lambda` Functions:
Lambda functions are most commonly used in situations where a small, throw-away function is required for a short period, especially as an argument to higher-order functions (functions that take other functions as arguments). Common scenarios include:
-
Arguments to functions that expect a callable:
- `map()`: Apply a function to each item in an iterable.
- `filter()`: Filter items from an iterable based on a condition.
- `sorted()`: Provide a custom key for sorting.
- `min()`, `max()`: Provide a custom key for finding minimum/maximum.
- Event handlers in GUI programming (e.g., Tkinter, PyQt).
- Closures: Though less common than `def`, lambdas can form closures.
- Simple transformations: When a one-liner transformation or calculation is needed without the verbosity of a full function definition.
While `lambda` functions offer conciseness, it's generally recommended to use regular `def` functions for more complex logic or when the function needs to be reused or documented. Overusing `lambda` for non-trivial tasks can sometimes decrease readability.
# --- Example 1: Basic Lambda Function ---
# A lambda function to add two numbers
add = lambda x, y: x + y
print("--- Basic Lambda ---")
print(f"Sum of 5 and 3: {add(5, 3)}") # Output: 8
print(f"Type of add: {type(add)}") # Output: <class 'function'>
# --- Example 2: Using lambda with `map()` ---
print("\n--- Lambda with map() ---")
numbers = [1, 2, 3, 4, 5]
# Double each number using lambda
doubled_numbers = list(map(lambda num: num * 2, numbers))
print(f"Original numbers: {numbers}")
print(f"Doubled numbers (using map + lambda): {doubled_numbers}") # Output: [2, 4, 6, 8, 10]
# --- Example 3: Using lambda with `filter()` ---
print("\n--- Lambda with filter() ---")
# Filter out even numbers using lambda
even_numbers = list(filter(lambda num: num % 2 == 0, numbers))
print(f"Original numbers: {numbers}")
print(f"Even numbers (using filter + lambda): {even_numbers}") # Output: [2, 4]
# --- Example 4: Using lambda with `sorted()` (custom sort key) ---
print("\n--- Lambda with sorted() ---")
students = [('Alice', 20), ('Bob', 25), ('Charlie', 18)]
# Sort students by age using lambda as the key
sorted_by_age = sorted(students, key=lambda student: student[1])
print(f"Students sorted by age: {sorted_by_age}") # Output: [('Charlie', 18), ('Alice', 20), ('Bob', 25)]
words = ["apple", "banana", "kiwi", "grapefruit"]
# Sort words by length
sorted_by_length = sorted(words, key=lambda word: len(word))
print(f"Words sorted by length: {sorted_by_length}") # Output: ['kiwi', 'apple', 'banana', 'grapefruit']
# --- Example 5: Lambda with a conditional expression ---
print("\n--- Lambda with Conditional Expression ---")
check_parity = lambda num: "Even" if num % 2 == 0 else "Odd"
print(f"Is 7 Even or Odd? {check_parity(7)}") # Output: Odd
print(f"Is 10 Even or Odd? {check_parity(10)}") # Output: Even
# --- Example 6: Lambda acting as a simple closure (less common for lambda) ---
print("\n--- Lambda as a Closure ---")
def make_multiplier(factor):
# 'factor' is captured from the enclosing scope
return lambda x: x * factor
multiply_by_5 = make_multiplier(5)
multiply_by_10 = make_multiplier(10)
print(f"5 * 6: {multiply_by_5(6)}") # Output: 30
print(f"10 * 6: {multiply_by_10(6)}") # Output: 60
Explanation of the Example Code:
-
**Basic Lambda:**
- `add = lambda x, y: x + y` defines an anonymous function that takes two arguments `x` and `y` and returns their sum. It's then assigned to the variable `add`, behaving like a regular function. The `type(add)` confirms it's a function object.
-
**Lambda with `map()`:**
- `map(lambda num: num * 2, numbers)` applies the lambda function (`num * 2`) to each element (`num`) in the `numbers` list. `map()` returns an iterator, so `list()` is used to convert it into a list for printing. This concisely doubles every number.
-
**Lambda with `filter()`:**
- `filter(lambda num: num % 2 == 0, numbers)` uses the lambda to test each number (`num`) in `numbers`. Only numbers for which `num % 2 == 0` evaluates to `True` (i.e., even numbers) are kept. Again, `list()` is used to materialize the results.
-
**Lambda with `sorted()`:**
- The `key` argument in `sorted()` expects a function that takes one argument (an element from the iterable) and returns a value to use for comparison.
- `key=lambda student: student[1]` tells `sorted()` to use the second element (`student[1]`, which is the age) of each `student` tuple for sorting.
- Similarly, `key=lambda word: len(word)` sorts words based on their length.
-
**Lambda with Conditional Expression:**
- This example demonstrates that while lambdas cannot contain `if/else` *statements*, they can use a single `if/else` *expression* (also known as a ternary operator) to return different values based on a condition. `check_parity(num)` returns "Even" if `num` is even, "Odd" otherwise.
-
**Lambda as a Closure:**
- `make_multiplier(factor)` is a higher-order function that returns a lambda function. The returned lambda "remembers" the `factor` from its enclosing `make_multiplier` scope, even after `make_multiplier` has finished executing. This is a classic example of a closure.
The examples highlight `lambda` functions' role as concise, single-purpose callables, primarily used when a quick, inline function definition is sufficient and more verbose `def` function would be overkill.