Fun with Learning Technology
LearnCoursesQuestionsTracksToolsNewsExplorePractice
Fun with Learning Technology

A new problem, explained clearly, every day.

Subscribe
Learn
  • Lessons
  • Topics
  • News
  • Tools
  • Courses
  • Career tracks
  • Everything
Site
  • About
  • Contact
  • Support
  • Privacy
  • Terms
Get the daily one

One email per new problem. No spam.

Request a tutorial

Requests shape what gets made next.

© 2026 Fun with Learning TechnologyRSS
Home›Courses›Python›Lambda Functions

Functions

Lambda Functions

Lambda functions in Python are small, anonymous functions defined with the `lambda` keyword. They matter because they allow you to create quick, throwaway functions without formally defining them using `def`, making code more concise and readable in scenarios where a full function definition would be overkill. You reach for them when you need a simple function for a short operation, especially as arguments to higher-order functions like `map`, `filter`, or `sorted`.

What is a Lambda Function?

A lambda function is a way to create a small, unnamed function in Python. Unlike regular functions defined with `def`, lambda functions are restricted to a single expression, meaning they can only perform one operation. This limitation is intentional—it keeps them lightweight and focused. The syntax is `lambda arguments: expression`, where `arguments` are the inputs (like parameters in a regular function) and `expression` is the operation performed on those inputs. The result of the expression is automatically returned. Lambda functions are not meant to replace all functions but are ideal for simple, one-off operations where defining a full function would feel cumbersome. For example, if you need to square a number in a single line, a lambda function is perfect. Understanding this helps you recognize when a lambda is appropriate versus when a full function definition is better for clarity or reusability.

# A lambda function that squares a number
square = lambda x: x ** 2
print(square(5))  # Output: 25

# Equivalent to a regular function
def square_def(x):
    return x ** 2
print(square_def(5))  # Output: 25

# Lambda functions are often used inline
print((lambda x: x ** 2)(5))  # Output: 25

Why Use Lambda Functions?

Lambda functions shine in situations where you need a small function temporarily, especially as an argument to another function. For instance, when using `sorted`, `map`, or `filter`, you often need a simple function to determine how elements are processed. Writing a full `def` function for such a small task would clutter your code and distract from the main logic. Lambda functions keep the focus on the operation itself rather than the function's name or structure. They also make your code more readable when the operation is simple and self-explanatory. For example, sorting a list of tuples by the second element is cleaner with a lambda than defining a separate function. However, if the logic becomes complex or needs to be reused, a regular function is better. The key is to use lambdas for clarity and brevity, not to force them where they don’t fit.

# Sorting a list of tuples by the second element
students = [('Alice', 22), ('Bob', 19), ('Charlie', 21)]
sorted_students = sorted(students, key=lambda student: student[1])
print(sorted_students)  # Output: [('Bob', 19), ('Charlie', 21), ('Alice', 22)]

# Without lambda, you'd need a separate function
def get_age(student):
    return student[1]
sorted_students_def = sorted(students, key=get_age)
print(sorted_students_def)  # Same output

Lambda Functions with `map` and `filter`

Lambda functions are commonly used with `map` and `filter` because these functions expect another function as their first argument. `map` applies a function to every item in an iterable (like a list), while `filter` selects items based on a condition. Using a lambda here avoids the need to define a separate function, making the code more concise. For example, `map(lambda x: x * 2, numbers)` doubles each number in a list, and `filter(lambda x: x % 2 == 0, numbers)` keeps only the even numbers. The lambda’s simplicity aligns perfectly with the single-purpose nature of `map` and `filter`. However, if the operation is complex or needs to be reused, a regular function is still preferable. Understanding how lambdas interact with these functions helps you write cleaner, more Pythonic code without unnecessary boilerplate.

# Using map to double each number in a list
numbers = [1, 2, 3, 4]
doubled = list(map(lambda x: x * 2, numbers))
print(doubled)  # Output: [2, 4, 6, 8]

# Using filter to keep only even numbers
even_numbers = list(filter(lambda x: x % 2 == 0, numbers))
print(even_numbers)  # Output: [2, 4]

# Without lambda, you'd need separate functions
def double(x):
    return x * 2
def is_even(x):
    return x % 2 == 0
print(list(map(double, numbers)))  # Output: [2, 4, 6, 8]
print(list(filter(is_even, numbers)))  # Output: [2, 4]

Lambda Functions and Default Arguments

Lambda functions can include default arguments, just like regular functions. This allows you to create flexible lambdas that handle missing inputs gracefully. For example, `lambda x, y=10: x + y` will add `x` and `y`, but if `y` isn’t provided, it defaults to `10`. This is useful when you want a lambda to work in multiple contexts without requiring all arguments. However, default arguments in lambdas behave the same way as in regular functions—if a mutable default (like a list) is used, it can lead to unexpected behavior. For instance, `lambda x, lst=[]: lst.append(x)` will retain the list between calls, which might not be what you want. Understanding how defaults work in lambdas helps you avoid subtle bugs while keeping your code concise and adaptable.

# Lambda with a default argument
add = lambda x, y=10: x + y
print(add(5))      # Output: 15 (y defaults to 10)
print(add(5, 20))  # Output: 25 (y is 20)

# Be careful with mutable defaults
append_to_list = lambda x, lst=[]: lst.append(x) or lst
print(append_to_list(1))  # Output: [1]
print(append_to_list(2))  # Output: [1, 2] (lst retains state!)

# Safer alternative: use None and initialize inside
append_safe = lambda x, lst=None: (lst if lst is not None else []) + [x]
print(append_safe(1))  # Output: [1]
print(append_safe(2))  # Output: [2]

When Not to Use Lambda Functions

While lambda functions are powerful, they are not always the best choice. If the logic inside the lambda becomes complex or spans multiple lines, a regular function is more readable and maintainable. For example, a lambda with nested conditions or loops is harder to debug and understand than a named function. Additionally, if the function needs a docstring or type hints, a regular function is the only option. Lambdas are also limited to a single expression, so they cannot include statements like `return`, `assert`, or `raise`. Another drawback is that lambdas can make stack traces harder to read since they lack a descriptive name. Finally, if the function is reused in multiple places, defining it once with `def` is cleaner than repeating the lambda. Knowing when to avoid lambdas helps you write code that is easier to maintain and debug.

# Bad: Lambda with complex logic (hard to read)
complex_lambda = lambda x: (x * 2 if x > 0 else x / 2) if x != 0 else 0
print(complex_lambda(5))   # Output: 10
print(complex_lambda(-3))  # Output: -1.5
print(complex_lambda(0))   # Output: 0

# Better: Use a regular function for clarity
def process_number(x):
    if x == 0:
        return 0
    return x * 2 if x > 0 else x / 2
print(process_number(5))   # Output: 10
print(process_number(-3))  # Output: -1.5
print(process_number(0))   # Output: 0

# Lambdas cannot include statements like 'return'
# invalid_lambda = lambda x: return x * 2  # SyntaxError

Key points

  • Lambda functions are small, anonymous functions defined with the `lambda` keyword and are limited to a single expression.
  • They are useful for creating quick, throwaway functions without the need for a formal `def` definition, especially as arguments to higher-order functions.
  • Lambda functions improve code readability when the operation is simple and self-explanatory, but they should not replace regular functions for complex logic.
  • You can use lambda functions with `map`, `filter`, and `sorted` to perform operations or transformations on iterables concisely.
  • Lambda functions support default arguments, but you must be cautious with mutable defaults to avoid unexpected behavior.
  • Avoid using lambda functions when the logic is complex, spans multiple lines, or requires statements like `return` or `raise`.
  • Regular functions are better for reusable logic, docstrings, type hints, and debugging because they provide clearer stack traces.
  • Understanding when to use and when to avoid lambda functions helps you write cleaner, more maintainable Python code.

Common mistakes

  • Mistake: Using lambda functions for complex logic. Why it's wrong: Lambda functions are meant for simple, one-line expressions. Complex logic makes the code hard to read and debug. Fix: Use a regular `def` function for anything beyond a basic expression.
  • Mistake: Forgetting that lambda functions are anonymous. Why it's wrong: Lambda functions don’t have a name, so they can’t be reused or referenced later in the code. Fix: Assign the lambda to a variable if you need to reuse it, or use a `def` function for clarity.
  • Mistake: Overusing lambda functions in places where built-in functions would work. Why it's wrong: For example, using `lambda x: x * 2` instead of `operator.mul` or a list comprehension. This reduces readability and performance. Fix: Prefer built-in functions or standard constructs when possible.
  • Mistake: Assuming lambda functions create a new scope. Why it's wrong: Lambda functions inherit the scope of the enclosing function or global scope, which can lead to unexpected behavior with variables. Fix: Be mindful of variable scoping and avoid relying on mutable defaults or closures in lambdas.
  • Mistake: Using lambda functions with `map` or `filter` when list comprehensions are clearer. Why it's wrong: List comprehensions are often more readable and Pythonic for simple transformations. Fix: Use list comprehensions for straightforward operations unless performance is a critical concern.

Interview questions

What is a lambda function in Python, and how do you write one?

A lambda function in Python is a small, anonymous function defined with the `lambda` keyword. Unlike regular functions defined with `def`, lambda functions can have any number of arguments but only one expression, which is evaluated and returned. They are useful for short, simple operations where a full function definition would be unnecessary. For example, `add = lambda x, y: x + y` creates a lambda function that adds two numbers. The syntax is concise, making it ideal for quick operations like sorting or filtering, where you don’t need a named function.

When would you use a lambda function instead of a regular function?

You’d use a lambda function when you need a short, throwaway function that you won’t reuse elsewhere in your code. Lambda functions shine in situations where brevity is key, such as passing a simple operation as an argument to higher-order functions like `map()`, `filter()`, or `sorted()`. For example, `sorted(data, key=lambda x: x[1])` sorts a list of tuples by their second element. A regular function would be overkill here because the logic is trivial and only needed once. However, if the logic is complex or requires multiple statements, a regular function is better for readability and maintainability.

How does the `map()` function work with lambda functions? Provide an example.

The `map()` function applies a given function to every item of an iterable, like a list, and returns an iterator. When combined with a lambda function, it becomes a powerful tool for transforming data concisely. For example, if you have a list of numbers and want to square each one, you can write `squared = map(lambda x: x ** 2, numbers)`. Here, the lambda function `lambda x: x ** 2` is applied to each element in `numbers`. The result is an iterator, so you’d convert it to a list with `list(squared)` to see the output. This approach is cleaner than using a loop for simple transformations.

Compare using a lambda function with `filter()` versus a list comprehension for filtering a list. Which is better and why?

Both lambda functions with `filter()` and list comprehensions can filter a list, but they have trade-offs. For example, to filter even numbers from a list, you could use `filter(lambda x: x % 2 == 0, numbers)` or `[x for x in numbers if x % 2 == 0]`. The list comprehension is generally preferred because it’s more readable and Pythonic. It combines filtering and transformation in one step, whereas `filter()` only filters. Additionally, list comprehensions are faster in most cases because they’re optimized for Python’s interpreter. However, `filter()` with a lambda can be useful when working with functional programming paradigms or when you need to pass the filtering logic as an argument to another function.

Explain how lambda functions work with the `sorted()` function to customize sorting. Provide an example with a list of dictionaries.

The `sorted()` function in Python allows you to customize sorting using the `key` parameter, which accepts a function. A lambda function is perfect for this because it lets you define the sorting logic inline. For example, if you have a list of dictionaries representing people and want to sort them by age, you’d write `sorted(people, key=lambda x: x['age'])`. Here, the lambda function extracts the `age` value from each dictionary, and `sorted()` uses these values to determine the order. This approach is flexible—you could sort by any key, like name or ID, by changing the lambda. Without a lambda, you’d need a separate function, which is less concise for simple cases.

What are the limitations of lambda functions in Python, and why might they be problematic in larger codebases?

Lambda functions in Python have several limitations that can make them problematic in larger codebases. First, they can only contain a single expression, so complex logic must be written as a regular function. Second, they lack a name, which makes debugging harder because error messages won’t reference a function name. Third, they can’t include statements like `return`, `assert`, or `raise`, limiting their use to simple operations. Finally, overusing lambdas can reduce code readability, especially if the logic isn’t trivial. For example, a lambda like `lambda x: (x[0] * 2, x[1] + 3)` is harder to understand than a named function with comments. In larger projects, clarity and maintainability are critical, so lambdas should be used sparingly and only for simple, one-off operations.

All Python interview questions →

Check yourself

1. What is the output of the following code? `nums = [1, 2, 3, 4]; result = list(map(lambda x: x * 2, nums))`

  • A.[1, 2, 3, 4]
  • B.[2, 4, 6, 8]
  • C.[1, 4, 9, 16]
  • D.[0, 2, 4, 6]
Show answer

B. [2, 4, 6, 8]
The correct answer is `[2, 4, 6, 8]` because the lambda function multiplies each element in `nums` by 2. The other options are incorrect: the first option doesn’t modify the list, the third squares the elements, and the fourth subtracts 1 before multiplying.

2. Which of the following is a valid use of a lambda function?

  • A.Sorting a list of tuples by the second element: `sorted(tuples, key=lambda x: x[1])`
  • B.Defining a recursive function: `factorial = lambda n: n * factorial(n-1)`
  • C.Creating a function with multiple statements: `lambda x: print(x); return x * 2`
  • D.Using a lambda as a default argument in a function: `def foo(x=lambda: 5): return x()`
Show answer

A. Sorting a list of tuples by the second element: `sorted(tuples, key=lambda x: x[1])`
The correct answer is sorting a list of tuples by the second element. Lambdas are ideal for simple, one-line operations like this. The other options are incorrect: recursion in lambdas is possible but discouraged, lambdas cannot contain multiple statements, and using lambdas as default arguments can lead to unexpected behavior due to mutable defaults.

3. What does the following code output? `pairs = [(1, 'a'), (2, 'b'), (3, 'c')]; print(sorted(pairs, key=lambda pair: pair[1]))`

  • A.[(1, 'a'), (2, 'b'), (3, 'c')]
  • B.[(3, 'c'), (2, 'b'), (1, 'a')]
  • C.[('a', 1), ('b', 2), ('c', 3)]
  • D.[(1, 'a'), (3, 'c'), (2, 'b')]
Show answer

A. [(1, 'a'), (2, 'b'), (3, 'c')]
The correct answer is `[(1, 'a'), (2, 'b'), (3, 'c')]` because the lambda sorts the tuples by the second element (the string), and the strings are already in alphabetical order. The other options are incorrect: the second option reverses the order, the third swaps the tuple elements, and the fourth sorts incorrectly.

4. Why might the following code raise an error? `add = lambda x, y: x + y; print(add(5))`

  • A.Lambda functions cannot take more than one argument.
  • B.The lambda is missing a default value for `y`.
  • C.The lambda is called with too few arguments.
  • D.Lambda functions cannot be assigned to variables.
Show answer

C. The lambda is called with too few arguments.
The correct answer is that the lambda is called with too few arguments. The lambda expects two arguments (`x` and `y`), but only one is provided. The other options are incorrect: lambdas can take multiple arguments, default values are allowed but not required, and lambdas can be assigned to variables.

5. Which of the following is NOT a good use case for a lambda function?

  • A.As a key function for sorting: `sorted(data, key=lambda x: x['age'])`
  • B.For a simple mathematical operation: `square = lambda x: x ** 2`
  • C.To define a function with a docstring: `func = lambda x: "This squares x" or x ** 2`
  • D.In a `filter` operation: `list(filter(lambda x: x % 2 == 0, numbers))`
Show answer

C. To define a function with a docstring: `func = lambda x: "This squares x" or x ** 2`
The correct answer is defining a function with a docstring. Lambdas cannot have docstrings, and the example provided is syntactically incorrect. The other options are valid use cases: lambdas work well for sorting keys, simple operations, and filtering.

Take the full Python quiz →

← PreviousReturn Values and Multiple ReturnsNext →Recursion

Python

78 lessons, free to read.

All lessons →

Track your progress

Sign in to mark lessons done, score quizzes and keep notes.

Open in the app