A lambda function in Python is an anonymous function that can have any number of arguments but can only have one expression. The syntax for Python lambda functions is straightforward: lambda arguments: expression
. Unlike regular functions defined with def
, lambda functions don’t require a return statement - they automatically return the result of their expression.
# Regular function
def add_numbers(x, y):
return x + y
# Equivalent lambda function
add_lambda = lambda x, y: x + y
The fundamental syntax of Python lambda functions follows this pattern:
lambda argument1, argument2, ...: expression
Key Properties:
# Single argument lambda
square = lambda x: x ** 2
print(square(5)) # Output: 25
# Multiple arguments lambda
multiply = lambda a, b, c: a * b * c
print(multiply(2, 3, 4)) # Output: 24
# No arguments lambda
greeting = lambda: "Hello, World!"
print(greeting()) # Output: Hello, World!
Python lambda functions support default arguments just like regular functions:
# Lambda with default argument
power = lambda base, exponent=2: base ** exponent
print(power(5)) # Output: 25 (5^2)
print(power(5, 3)) # Output: 125 (5^3)
# Lambda with multiple default arguments
calculator = lambda x, y=10, z=5: x + y * z
print(calculator(1)) # Output: 51 (1 + 10 * 5)
print(calculator(1, 2)) # Output: 11 (1 + 2 * 5)
print(calculator(1, 2, 3)) # Output: 7 (1 + 2 * 3)
Lambda functions can include conditional expressions using the ternary operator:
# Lambda with conditional expression
max_value = lambda x, y: x if x > y else y
print(max_value(10, 20)) # Output: 20
# Lambda for checking even/odd
is_even = lambda n: "Even" if n % 2 == 0 else "Odd"
print(is_even(8)) # Output: Even
print(is_even(7)) # Output: Odd
# Lambda with nested conditions
grade_checker = lambda score: "A" if score >= 90 else "B" if score >= 80 else "C" if score >= 70 else "F"
print(grade_checker(85)) # Output: B
The map()
function applies a lambda function to each item in an iterable:
# Lambda with map for squaring numbers
numbers = [1, 2, 3, 4, 5]
squared = list(map(lambda x: x ** 2, numbers))
print(squared) # Output: [1, 4, 9, 16, 25]
# Lambda with map for string operations
words = ["python", "lambda", "function"]
capitalized = list(map(lambda word: word.upper(), words))
print(capitalized) # Output: ['PYTHON', 'LAMBDA', 'FUNCTION']
# Lambda with map for temperature conversion
celsius = [0, 20, 30, 40]
fahrenheit = list(map(lambda c: (c * 9/5) + 32, celsius))
print(fahrenheit) # Output: [32.0, 68.0, 86.0, 104.0]
The filter()
function uses lambda functions to filter elements from an iterable:
# Lambda with filter for even numbers
numbers = [1, 2, 3, 4, 5, 6, 7, 8, 9, 10]
even_numbers = list(filter(lambda x: x % 2 == 0, numbers))
print(even_numbers) # Output: [2, 4, 6, 8, 10]
# Lambda with filter for string length
words = ["cat", "elephant", "dog", "butterfly", "ant"]
long_words = list(filter(lambda word: len(word) > 5, words))
print(long_words) # Output: ['elephant', 'butterfly']
# Lambda with filter for positive numbers
mixed_numbers = [-5, -2, 0, 3, 7, -1, 9]
positive = list(filter(lambda x: x > 0, mixed_numbers))
print(positive) # Output: [3, 7, 9]
The reduce()
function from functools module applies lambda functions cumulatively:
from functools import reduce
# Lambda with reduce for sum
numbers = [1, 2, 3, 4, 5]
total = reduce(lambda x, y: x + y, numbers)
print(total) # Output: 15
# Lambda with reduce for product
product = reduce(lambda x, y: x * y, numbers)
print(product) # Output: 120
# Lambda with reduce for finding maximum
maximum = reduce(lambda x, y: x if x > y else y, numbers)
print(maximum) # Output: 5
Lambda functions are extremely useful for custom sorting operations:
# Lambda for sorting tuples by second element
students = [("Alice", 85), ("Bob", 92), ("Charlie", 78), ("Diana", 96)]
sorted_by_grade = sorted(students, key=lambda student: student[1])
print(sorted_by_grade) # Output: [('Charlie', 78), ('Alice', 85), ('Bob', 92), ('Diana', 96)]
# Lambda for sorting strings by length
words = ["python", "java", "c", "javascript", "go"]
sorted_by_length = sorted(words, key=lambda word: len(word))
print(sorted_by_length) # Output: ['c', 'go', 'java', 'python', 'javascript']
# Lambda for reverse sorting
numbers = [3, 1, 4, 1, 5, 9, 2, 6]
reverse_sorted = sorted(numbers, key=lambda x: x, reverse=True)
print(reverse_sorted) # Output: [9, 6, 5, 4, 3, 2, 1, 1]
Lambda functions work seamlessly with dictionary operations:
# Lambda for dictionary value transformation
prices = {"apple": 0.5, "banana": 0.3, "orange": 0.8}
discounted = {key: lambda price: price * 0.9 for key in prices}
# Apply lambda to get discounted prices
final_prices = {key: func(prices[key]) for key, func in discounted.items()}
print(final_prices) # Output: {'apple': 0.45, 'banana': 0.27, 'orange': 0.72}
# Lambda for sorting dictionary by values
sorted_prices = dict(sorted(prices.items(), key=lambda item: item[1]))
print(sorted_prices) # Output: {'banana': 0.3, 'apple': 0.5, 'orange': 0.8}
Combining lambda functions with list comprehensions creates powerful data processing patterns:
# Lambda in list comprehension for complex transformations
data = [1, 2, 3, 4, 5]
transformed = [(lambda x: x ** 2)(num) for num in data]
print(transformed) # Output: [1, 4, 9, 16, 25]
# Lambda with conditional list comprehension
processed = [(lambda x: x * 2 if x % 2 == 0 else x * 3)(num) for num in data]
print(processed) # Output: [3, 4, 9, 8, 15]
Lambda functions can be nested to create more complex operations:
# Nested lambda for currying
add = lambda x: lambda y: x + y
add_five = add(5)
result = add_five(10)
print(result) # Output: 15
# Nested lambda for function composition
compose = lambda f, g: lambda x: f(g(x))
square = lambda x: x ** 2
double = lambda x: x * 2
square_then_double = compose(double, square)
print(square_then_double(3)) # Output: 18 (3^2 * 2)
While lambda functions can’t contain try-except blocks, you can use them with exception-safe operations:
# Lambda with safe division
safe_divide = lambda x, y: x / y if y != 0 else float('inf')
print(safe_divide(10, 2)) # Output: 5.0
print(safe_divide(10, 0)) # Output: inf
# Lambda with default values for safe operations
safe_access = lambda lst, index, default=None: lst[index] if 0 <= index < len(lst) else default
my_list = [1, 2, 3, 4, 5]
print(safe_access(my_list, 2)) # Output: 3
print(safe_access(my_list, 10)) # Output: None
# Processing customer data
customers = [
{"name": "John", "age": 25, "city": "New York"},
{"name": "Jane", "age": 30, "city": "London"},
{"name": "Bob", "age": 35, "city": "Paris"},
{"name": "Alice", "age": 28, "city": "Tokyo"}
]
# Lambda for filtering customers by age
adults = list(filter(lambda customer: customer["age"] >= 30, customers))
print(f"Adults: {len(adults)}") # Output: Adults: 2
# Lambda for extracting names
names = list(map(lambda customer: customer["name"], customers))
print(f"Names: {names}") # Output: Names: ['John', 'Jane', 'Bob', 'Alice']
# Lambda for sorting by age
sorted_customers = sorted(customers, key=lambda customer: customer["age"])
print(f"Youngest: {sorted_customers[0]['name']}") # Output: Youngest: John
import math
# Lambda for mathematical calculations
operations = {
"square": lambda x: x ** 2,
"cube": lambda x: x ** 3,
"sqrt": lambda x: math.sqrt(x),
"factorial": lambda x: math.factorial(x) if x >= 0 else None
}
number = 5
for operation, func in operations.items():
result = func(number)
print(f"{operation}({number}) = {result}")
# Output:
# square(5) = 25
# cube(5) = 125
# sqrt(5) = 2.23606797749979
# factorial(5) = 120
Here’s a comprehensive example that demonstrates various lambda function applications in a real-world scenario:
from functools import reduce
from datetime import datetime
import json
# Sample sales data
sales_data = [
{"product": "laptop", "price": 999.99, "quantity": 2, "date": "2024-01-15"},
{"product": "mouse", "price": 29.99, "quantity": 5, "date": "2024-01-16"},
{"product": "keyboard", "price": 79.99, "quantity": 3, "date": "2024-01-17"},
{"product": "monitor", "price": 299.99, "quantity": 1, "date": "2024-01-18"},
{"product": "laptop", "price": 999.99, "quantity": 1, "date": "2024-01-19"}
]
# Lambda functions for data analysis
calculate_total = lambda item: item["price"] * item["quantity"]
is_expensive = lambda item: item["price"] > 100
product_name = lambda item: item["product"]
get_date = lambda item: datetime.strptime(item["date"], "%Y-%m-%d")
# Apply lambda functions for analysis
print("=== Sales Data Analysis ===")
# Calculate total value for each sale
sales_with_totals = list(map(
lambda item: {**item, "total_value": calculate_total(item)},
sales_data
))
# Find expensive items
expensive_items = list(filter(is_expensive, sales_data))
print(f"Expensive items count: {len(expensive_items)}")
# Get unique products
unique_products = list(set(map(product_name, sales_data)))
print(f"Unique products: {unique_products}")
# Calculate total revenue
total_revenue = reduce(
lambda acc, item: acc + calculate_total(item),
sales_data,
0
)
print(f"Total revenue: ${total_revenue:.2f}")
# Sort by date
sorted_by_date = sorted(sales_data, key=get_date)
print(f"First sale: {sorted_by_date[0]['product']} on {sorted_by_date[0]['date']}")
# Group by product (using lambda with dictionary)
product_summary = {}
for item in sales_data:
product = product_name(item)
if product not in product_summary:
product_summary[product] = {"count": 0, "total_value": 0}
product_summary[product]["count"] += item["quantity"]
product_summary[product]["total_value"] += calculate_total(item)
# Sort products by total value
sorted_products = sorted(
product_summary.items(),
key=lambda x: x[1]["total_value"],
reverse=True
)
print("\n=== Product Summary (sorted by total value) ===")
for product, data in sorted_products:
print(f"{product}: {data['count']} units, ${data['total_value']:.2f}")
# Advanced lambda usage: Create a sales report generator
generate_report = lambda data: {
"total_items": reduce(lambda acc, item: acc + item["quantity"], data, 0),
"total_revenue": reduce(lambda acc, item: acc + calculate_total(item), data, 0),
"average_price": reduce(lambda acc, item: acc + item["price"], data, 0) / len(data),
"most_expensive": max(data, key=lambda item: item["price"]),
"date_range": {
"start": min(data, key=get_date)["date"],
"end": max(data, key=get_date)["date"]
}
}
# Generate and display report
report = generate_report(sales_data)
print("\n=== Sales Report ===")
print(json.dumps(report, indent=2, default=str))
Expected Output:
=== Sales Data Analysis ===
Expensive items count: 3
Unique products: ['laptop', 'mouse', 'keyboard', 'monitor']
Total revenue: $2939.86
First sale: laptop on 2024-01-15
=== Product Summary (sorted by total value) ===
laptop: 3 units, $2999.97
monitor: 1 units, $299.99
keyboard: 3 units, $239.97
mouse: 5 units, $149.95
=== Sales Report ===
{
"total_items": 12,
"total_revenue": 3689.88,
"average_price": 481.99,
"most_expensive": {
"product": "laptop",
"price": 999.99,
"quantity": 2,
"date": "2024-01-15"
},
"date_range": {
"start": "2024-01-15",
"end": "2024-01-19"
}
}
This comprehensive example demonstrates how Python lambda functions can be effectively used for data processing, filtering, mapping, and analysis tasks. The lambda functions provide a clean, readable way to perform complex operations on data structures while maintaining code conciseness and functional programming principles.
Lambda functions in Python offer a powerful tool for writing concise, functional code. They excel in scenarios involving data transformation, filtering, sorting, and functional programming patterns. While they have limitations compared to regular functions, their simplicity and inline nature make them invaluable for specific use cases, especially when working with higher-order functions and data processing operations.