Swiftorial Logo
Home
Swift Lessons
Tutorials
Learn More
Career
Resources

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.