Python Lambda Functions: When and How to Use Them
Lambda functions are anonymous, one-line functions in Python. They're powerful when used correctly, but often misused. Here's the complete guide:
1. Basic Syntax
# Regular function
def square(x):
return x ** 2
# Lambda equivalent
square = lambda x: x ** 2
# Usage is identical
square(5) # 25
# Lambda syntax: lambda arguments: expression
# - No return statement (implicit)
# - Single expression only
# - No statements allowed
2. Common Use Cases
# Sorting with custom key
students = [
{'name': 'Alice', 'grade': 85},
{'name': 'Bob', 'grade': 92},
{'name': 'Charlie', 'grade': 78}
]
# Sort by grade
sorted_students = sorted(students, key=lambda s: s['grade'])
# Sort by name length
sorted_by_name = sorted(students, key=lambda s: len(s['name']))
# Sort strings case-insensitive
words = ['banana', 'Apple', 'cherry']
sorted(words, key=lambda s: s.lower())
# ['Apple', 'banana', 'cherry']
3. With map(), filter(), reduce()
# map: Apply function to each element
numbers = [1, 2, 3, 4, 5]
squares = list(map(lambda x: x ** 2, numbers))
# [1, 4, 9, 16, 25]
# filter: Keep elements where function returns True
evens = list(filter(lambda x: x % 2 == 0, numbers))
# [2, 4]
# reduce: Accumulate values
from functools import reduce
total = reduce(lambda x, y: x + y, numbers)
# 15 (same as sum(numbers))
# Note: List comprehensions are often more readable:
squares = [x ** 2 for x in numbers] # Preferred
evens = [x for x in numbers if x % 2 == 0] # Preferred
4. Multiple Arguments
# Two arguments
add = lambda x, y: x + y
add(3, 5) # 8
# Three arguments
volume = lambda l, w, h: l * w * h
volume(2, 3, 4) # 24
# Practical: Sort by multiple keys
data = [('Alice', 25), ('Bob', 30), ('Alice', 20)]
sorted(data, key=lambda x: (x[0], x[1]))
# [('Alice', 20), ('Alice', 25), ('Bob', 30)]
5. Default Arguments
# Lambda with defaults
greet = lambda name, greeting='Hello': f"{greeting}, {name}!"
greet('Alice') # "Hello, Alice!"
greet('Bob', 'Hi') # "Hi, Bob!"
# Useful in sorting
prices = [100, 50, 200, None, 75]
sorted(prices, key=lambda x: x if x is not None else 0)
# [None, 50, 75, 100, 200]
6. Pandas/DataFrame Operations
import pandas as pd
df = pd.DataFrame({
'name': ['Alice', 'Bob', 'Charlie'],
'age': [25, 30, 35],
'salary': [50000, 60000, 75000]
})
# Apply lambda to column
df['age_group'] = df['age'].apply(lambda x: 'young' if x < 30 else 'senior')
# Apply to multiple columns
df['total_comp'] = df.apply(lambda row: row['salary'] * 1.1, axis=1)
# Filter rows
young_employees = df[df['age'].apply(lambda x: x < 30)]
# Map values
df['name_upper'] = df['name'].map(lambda x: x.upper())
7. When NOT to Use Lambda
# Bad: Complex logic ❌
process = lambda x: x * 2 if x > 0 else x / 2 if x < 0 else 0
# Good: Use def for readability ✅
def process(x):
if x > 0:
return x * 2
elif x < 0:
return x / 2
else:
return 0
# Bad: Assigning lambda to variable ❌
square = lambda x: x ** 2
# Good: Just use def ✅
def square(x):
return x ** 2
# Bad: Multiple statements (won't work) ❌
# Lambda can't do this:
# lambda x: print(x); return x
# Good: Use def ✅
def debug_and_return(x):
print(x)
return x
8. Practical Examples
# Sort files by extension
files = ['data.csv', 'report.pdf', 'image.png', 'script.py']
sorted(files, key=lambda f: f.split('.')[-1])
# ['data.csv', 'report.pdf', 'image.png', 'script.py']
# Extract specific fields
users = [
{'id': 1, 'name': 'Alice', 'active': True},
{'id': 2, 'name': 'Bob', 'active': False}
]
active_names = map(lambda u: u['name'], filter(lambda u: u['active'], users))
# ['Alice']
# Better with list comprehension:
active_names = [u['name'] for u in users if u['active']]
# Quick data transformation
prices = [10.99, 20.50, 5.25]
formatted = list(map(lambda p: f"${p:.2f}", prices))
# ['$10.99', '$20.50', '$5.25']
# Conditional mapping
numbers = [1, 2, 3, 4, 5]
labels = list(map(lambda x: 'even' if x % 2 == 0 else 'odd', numbers))
# ['odd', 'even', 'odd', 'even', 'odd']
9. Lambda with Built-in Functions
# max/min with key
students = [('Alice', 85), ('Bob', 92), ('Charlie', 78)]
top_student = max(students, key=lambda s: s[1])
# ('Bob', 92)
# groupby with key
from itertools import groupby
data = ['apple', 'apricot', 'banana', 'blueberry', 'cherry']
grouped = {k: list(v) for k, v in groupby(sorted(data), key=lambda x: x[0])}
# {'a': ['apple', 'apricot'], 'b': ['banana', 'blueberry'], 'c': ['cherry']}
# any/all with conditions
numbers = [2, 4, 6, 8]
all_even = all(map(lambda x: x % 2 == 0, numbers)) # True
has_large = any(map(lambda x: x > 5, numbers)) # True
10. Closures with Lambda
# Create multiplier functions
def make_multiplier(n):
return lambda x: x * n
times_2 = make_multiplier(2)
times_3 = make_multiplier(3)
times_2(5) # 10
times_3(5) # 15
# Partial application pattern
from functools import partial
# This is usually better than lambda for partial application
add = lambda x, y: x + y
add_5 = partial(add, 5)
add_5(3) # 8
Best Practices
- ✅ Use lambda for simple, one-line operations
- ✅ Perfect for
keyparameter in sorting - ✅ Good for quick transformations with map/filter
- ✅ Prefer list comprehensions when possible
- ❌ Don't assign lambda to variable (use
def) - ❌ Don't use for complex logic
- ❌ Don't use when you need multiple statements
- ⚠️ Can't include type hints (use
def)
Pro Tip: If your lambda is more than one simple expression, or if you're assigning it to a variable, use a regular function instead. Lambda is for throwaway functions, not named functions.
← Back to Python Tips