Skip to Content
Course content

76: When to Use Lambda vs a Named Function

Click on the "Edit" button in the top corner of the screen to edit your slide content.

Think about the difference between a Post-it note and a formal instruction manual. If you just need to remember to "buy milk" on your way home, you don't write a three-page documented procedure on how to navigate the grocery store, find the dairy aisle, and select the appropriate gallon of 2% milk. You scribble it on a Post-it, use it for ten minutes, and then toss it in the trash. But if you're teaching a new employee how to handle the company's payroll, you absolutely don't use a Post-it. You write a formal manual that can be referenced, audited, and updated over time.

In Python, a lambda is your Post-it note. A named function (using def) is your formal manual. Here is how that maps to your code:

  • The "Scribble" (Lambda): It's anonymous. It doesn't need a name because you're only using it right here, right now, usually as an argument to another function.
  • The "Manual" (Named Function): It has a name, a dedicated place in your script, and usually a docstring explaining why it exists.
  • The "Trash" (Lifecycle): A lambda is often created and destroyed in a single line of execution. A named function lives throughout the life of your program.

The Sweet Spot for Lambdas

I usually tell people to reach for a lambda when they are using "higher-order functions"—functions that take other functions as arguments. The most common culprits are sorted(), filter(), and map().

Imagine you have a list of employee dictionaries, and you want to sort them by their salary. You don't need to define a whole function just to tell Python "look at the salary key." That's a Post-it note task.

employees = [
    {"name": "Alice", "salary": 70000},
    {"name": "Bob", "salary": 50000},
    {"name": "Charlie", "salary": 60000}
]

# I don't need a formal function for this simple logic
sorted_employees = sorted(employees, key=lambda emp: emp['salary'])

It's concise, and it keeps the logic right where the action is happening. If I had used def get_salary(emp): return emp['salary'], I'd be adding two lines of boilerplate to my file for a piece of logic that will never be used anywhere else.

When the Post-it Gets Too Crowded

Here is where a lot of developers trip up: they try to cram too much into a lambda. The second you feel the urge to add complex logic, multiple conditions, or—heaven forbid—try to find a way to put a loop inside a lambda, stop. You've run out of room on your Post-it note.

If your logic requires an if/elif/else chain or performs a calculation that isn't immediately obvious to someone reading it, move it to a named function. Not only is it more readable, but it's also debuggable. You can't put a print() statement or a breakpoint inside a lambda very easily. In a named function, you can.

# BAD: This is a "crowded Post-it"
# Trying to calculate a complex bonus in a lambda is a nightmare to read
bonuses = map(lambda e: e['salary'] * 0.1 if e['salary'] < 60000 else e['salary'] * 0.05, employees)

# BETTER: This is a "formal manual"
def calculate_bonus(employee):
    """Determines bonus percentage based on salary bracket."""
    if employee['salary'] < 60000:
        return employee['salary'] * 0.1
    return employee['salary'] * 0.05

bonuses = map(calculate_bonus, employees)

I'll be honest: some people love the "one-liner" aesthetic. But as a senior dev reviewing your code, I don't care about how few lines you used; I care about how quickly I can understand what the code is doing without having to squint at a nested ternary operator. When in doubt, name it.




📋 Practical Task

Refactoring the Warehouse Inventory Processor

You have been handed a piece of code that processes a list of warehouse items. The original developer used lambdas for everything, and now the logic has become a mess. Your task is to refactor this code by deciding which logic stays as a lambda and which logic deserves a named function.

inventory = [
    {"item": "Laptop", "price": 1200, "quantity": 5, "category": "Electronics"},
    {"item": "Desk Chair", "price": 150, "quantity": 20, "category": "Furniture"},
    {"item": "Monitor", "price": 300, "quantity": 10, "category": "Electronics"},
    {"item": "Notebook", "price": 5, "quantity": 100, "category": "Stationery"},
]

# TASK 1: Keep this as a lambda. 
# Sort the inventory by price (lowest to highest).
sorted_inventory = sorted(inventory, key=lambda x: x['price'])

# TASK 2: Refactor this into a named function called 'calculate_total_value'.
# The logic: multiply price by quantity.
# Currently it is: total_values = map(lambda x: x['price'] * x['quantity'], inventory)
# [Your refactored code here]

# TASK 3: Refactor this into a named function called 'is_high_value_stock'.
# The logic: An item is high value if it's in 'Electronics' AND has a total value (price * qty) > 1000.
# Currently it is: high_value = filter(lambda x: x['category'] == 'Electronics' and (x['price'] * x['quantity']) > 1000, inventory)
# [Your refactored code here]

Requirements:

  1. The sorting logic must remain a lambda.
  2. The total value calculation must be moved to a named function.
  3. The high-value stock filter must be moved to a named function with a clear docstring.
Rating
0 0

There are no comments for now.

to be the first to leave a comment.