
Python Course
Lambda Functions in Python
In Lesson 16, you learned how to write functions using def — named, multi-line, reusable blocks of code. Python also gives you a second way to write functions: the lambda. A lambda is a compact, single-expression function that fits on one line and requires no name, no def, and no return keyword.
Lambdas are not a replacement for regular functions — they are a different tool for a different job. They shine when you need a short, one-time function to pass directly as an argument to another function like map(), filter(), sorted(), or reduce(). Every professional Python developer uses lambdas constantly, and you will see them throughout data science libraries, web frameworks, and backend code.
The Lambda Syntax
The syntax of a lambda is simpler than it looks:
# Syntax: lambda parameters : expression
# A lambda that multiplies a number by 2
double = lambda x : x * 2
print(double(5)) # 10
print(double(12)) # 24
# A lambda with two parameters
add = lambda a, b : a + b
print(add(10, 5)) # 15
# A lambda with no parameters
greet = lambda : "Hello from lambda!"
print(greet())
- Everything after the colon is the return value — no
returnkeyword needed. - A lambda can take zero, one, or many parameters separated by commas.
- The entire expression must fit on one line — you cannot write
if/elseblocks or multiple statements inside a lambda.
Lambda vs Regular Function — Side by Side
The best way to understand a lambda is to see it next to the equivalent def function. Both produce identical results — the lambda is simply more compact.
# Regular function
def square(n):
return n * n
# Lambda — identical result, one line
square_l = lambda n : n * n
print(square(7)) # 49
print(square_l(7)) # 49
# Regular function
def celsius_to_f(c):
return (c * 9/5) + 32
# Lambda
celsius_to_f_l = lambda c : (c * 9/5) + 32
print(celsius_to_f(100)) # 212.0
print(celsius_to_f_l(100)) # 212.0
- Both versions are correct — the lambda is a shorthand, not a different concept.
- Notice there is no function name in the lambda definition — it is assigned to a variable here only so we can call it by that name later.
- In real usage, lambdas are most often used inline — passed directly as arguments — rather than stored in a variable like this.
Lambda with One Parameter — Practical Examples
Single-parameter lambdas are used for quick transformations on individual values. They are especially useful when applied to every item in a list using map().
# Check if a number is even
is_even = lambda n : n % 2 == 0
print(is_even(4)) # True
print(is_even(7)) # False
# Make a string shout (uppercase + exclamation)
shout = lambda text : text.upper() + "!"
print(shout("welcome to python"))
# Round a float to 2 decimal places
round2 = lambda x : round(x, 2)
print(round2(3.14159)) # 3.14
print(round2(99.9876)) # 99.99
# Extract the domain from an email address
get_domain = lambda email : email.split("@")[1]
print(get_domain("user@dataplexa.com"))
print(get_domain("admin@gmail.com"))
- Lambdas can chain multiple string or list operations in one expression — as long as it is one continuous expression, it works.
email.split("@")[1]— splits the email at the@sign and takes the second part. This kind of text extraction is very common in data cleaning.
Lambda with map() — Transform Every Item
map(function, iterable) applies a function to every item in a list and returns the transformed results. Combined with a lambda, this replaces an entire loop in a single line. It is one of the most powerful combinations in Python.
prices = [100, 250, 80, 500, 175]
# Apply 10% discount to every price
discounted = list(map(lambda p : round(p * 0.9, 2), prices))
print("Original :", prices)
print("Discounted:", discounted)
# Convert celsius to fahrenheit for a list of temperatures
temps_c = [0, 20, 37, 100]
temps_f = list(map(lambda c : round((c * 9/5) + 32, 1), temps_c))
print("Celsius :", temps_c)
print("Fahrenheit:", temps_f)
# Capitalise every name in a list
names = ["priya", "kiran", "arjun", "sneha"]
titled = list(map(lambda n : n.title(), names))
print("Titled names:", titled)
# Extract lengths of every word
words = ["Python", "is", "incredible", "and", "powerful"]
lengths = list(map(lambda w : len(w), words))
print("Word lengths:", lengths)
map()returns a lazy iterator — wrap it inlist()to get a regular list you can print or index.- Without lambda + map, each example above would need a loop, an empty list, and
append()— three extra lines. Lambda + map collapses that into one. - You can also pass a regular named function to
map()—map(str.upper, names)works too. Lambda gives you the flexibility to write custom logic inline.
Lambda with filter() — Keep Only What Passes
filter(function, iterable) keeps only the items from a list where the function returns True. The lambda defines the condition. Items that do not pass are silently discarded.
numbers = [3, 18, 7, 42, 5, 30, 11, 60, 2, 91]
# Keep only even numbers
evens = list(filter(lambda n : n % 2 == 0, numbers))
print("Even:", evens)
# Keep only numbers greater than 15
big = list(filter(lambda n : n > 15, numbers))
print("Greater than 15:", big)
# Keep only odd numbers less than 20
odd_small = list(filter(lambda n : n % 2 != 0 and n < 20, numbers))
print("Odd and under 20:", odd_small)
# Filter a list of emails — keep only Gmail addresses
emails = ["user@dataplexa.com", "admin@gmail.com", "test@yahoo.com", "hr@gmail.com"]
gmails = list(filter(lambda e : e.endswith("@gmail.com"), emails))
print("Gmail only:", gmails)
# Filter names longer than 4 characters
names = ["Jo", "Priya", "Kim", "Arjun", "Lee", "Sneha"]
long_names = list(filter(lambda n : len(n) > 4, names))
print("Long names:", long_names)
- You can combine multiple conditions inside a filter lambda using
and/or— as long as the whole thing is one expression. e.endswith("@gmail.com")— a clean real-world pattern for filtering email lists by domain.- Unlike
map(), the list returned byfilter()may be shorter than the original — only passing items survive.
Lambda with sorted() — Sort by Any Field
The sorted() function has a key parameter that accepts a function. That function extracts the value Python should use when deciding the order. A lambda makes this extremely clean — you can sort a list of tuples, dictionaries, or objects by any field in one line.
# Sort a list of tuples by the second element (price)
products = [
("Keyboard", 1200),
("Mouse", 599),
("Monitor", 8500),
("Webcam", 2200),
("Headset", 1800)
]
by_price = sorted(products, key=lambda item : item[1])
print("By price (low to high):")
for name, price in by_price:
print(f" {name:<12} Rs.{price}")
# Sort the same list alphabetically by name
by_name = sorted(products, key=lambda item : item[0])
print("By name (A-Z):")
for name, price in by_name:
print(f" {name}")
# Sort by string length — shortest word first
words = ["Python", "is", "an", "incredible", "language"]
by_length = sorted(words, key=lambda w : len(w))
print("By length:", by_length)
key=lambda item : item[1]tellssorted()to look at the second element of each tuple when deciding order.key=lambda item : item[0]sorts alphabetically by the first element — the name.- Add
reverse=Trueto anysorted()call to flip the order from ascending to descending — no extra code needed.
Sorting a List of Dictionaries
Real programs frequently work with lists of dictionaries — users from a database, products from an API, records from a CSV. Lambdas make sorting this kind of data by any field completely straightforward.
students = [
{"name": "Priya", "score": 88, "age": 21},
{"name": "Kiran", "score": 72, "age": 23},
{"name": "Arjun", "score": 95, "age": 20},
{"name": "Sneha", "score": 80, "age": 22},
{"name": "Rahul", "score": 65, "age": 24}
]
# Sort by score — highest first
by_score = sorted(students, key=lambda s : s["score"], reverse=True)
print("Ranked by score:")
for i, s in enumerate(by_score, 1):
print(f" {i}. {s['name']:<10} {s['score']}")
# Sort by name alphabetically
by_name = sorted(students, key=lambda s : s["name"])
print("Alphabetical by name:")
for s in by_name:
print(f" {s['name']}")
# Sort by age — youngest first
by_age = sorted(students, key=lambda s : s["age"])
print("By age (youngest first):")
for s in by_age:
print(f" {s['name']}, age {s['age']}")
- Changing what you sort by is as simple as changing the key inside the lambda —
s["score"],s["name"],s["age"]. - This pattern is used in every leaderboard, ranking table, and data report in real applications.
- You can also sort by multiple fields — sort by score descending, then by name ascending as a tiebreaker:
key=lambda s : (-s["score"], s["name"]).
Lambda with a Conditional Expression
A lambda can include a one-line if/else — called a conditional expression or ternary expression. The format is: value_if_true if condition else value_if_false. This lets you add simple branching inside a lambda without breaking the one-line rule.
# Label a number as Even or Odd
label = lambda n : "Even" if n % 2 == 0 else "Odd"
print(label(4)) # Even
print(label(7)) # Odd
# Pass or Fail based on score
result = lambda score : "Pass" if score >= 50 else "Fail"
print(result(75)) # Pass
print(result(40)) # Fail
# Apply different discount based on quantity ordered
discount = lambda qty : 20 if qty >= 10 else (10 if qty >= 5 else 0)
print("Qty 15 →", discount(15), "% off")
print("Qty 7 →", discount(7), "% off")
print("Qty 2 →", discount(2), "% off")
# Grade based on score — multiple nested conditions
grade = lambda s : "A" if s >= 90 else ("B" if s >= 75 else ("C" if s >= 60 else "F"))
for score in [95, 82, 67, 45]:
print(f"Score {score} → Grade {grade(score)}")
- Nested ternary expressions —
a if cond1 else (b if cond2 else c)— work in lambdas but get hard to read quickly. Use them for 2–3 conditions maximum; beyond that, switch to adef. - The discount lambda chains two conditions with nested ternary logic — practical for tier-based pricing rules.
Lambda with reduce() — Fold a List into One Value
reduce() from Python's functools module applies a function to the first two items of a list, then to the result and the third item, and so on — until the entire list is collapsed into a single value. It is the functional programming way to build running totals, products, or any accumulation.
from functools import reduce
numbers = [1, 2, 3, 4, 5]
# Sum all numbers (same as sum())
total = reduce(lambda a, b : a + b, numbers)
print("Sum:", total) # 15
# Product of all numbers
product = reduce(lambda a, b : a * b, numbers)
print("Product:", product) # 120
# Find the maximum value manually
max_val = reduce(lambda a, b : a if a > b else b, numbers)
print("Max:", max_val) # 5
# Concatenate a list of strings
words = ["Python", " is", " powerful"]
sentence = reduce(lambda a, b : a + b, words)
print("Sentence:", sentence)
# Running total of sales
sales = [1200, 850, 2300, 450, 3100]
grand_total = reduce(lambda acc, sale : acc + sale, sales)
print("Grand total:", grand_total)
reduce(lambda a, b : a + b, [1,2,3,4,5])works like: ((((1+2)+3)+4)+5) = 15 — it processes left to right, two at a time.reducemust be imported fromfunctools— it was moved there in Python 3 becausesum(),max(), and loops handle most common cases better.- Use
reduce()for custom accumulation logic that built-ins cannot handle — like multiplying all values or building a running computation.
Immediately Invoked Lambda
You can call a lambda immediately without assigning it to a variable — useful for one-off calculations inside other expressions.
# Define and call in the same line — wrap the lambda in ()
result = (lambda x, y : x ** y)(2, 10)
print("2^10 =", result)
# Useful inline inside print or other expressions
print("Circle area:", (lambda r : 3.14159 * r * r)(7))
# Common in data science notebooks for quick one-off transforms
data = [1, 4, 9, 16, 25]
roots = list(map(lambda x : (lambda n : n ** 0.5)(x), data))
print("Square roots:", roots)
(lambda x, y : x ** y)(2, 10)— the outer parentheses call the lambda immediately with2and10as arguments.- This pattern is called an IIFE (Immediately Invoked Function Expression) — more common in JavaScript but valid in Python for one-off calculations.
Lambda as a Function Argument — The Real Use Case
The most natural place for a lambda is as an argument directly inside a function call. This is where lambdas truly save time — you do not need to define a separate named function just to use it once.
# Sort a list of strings by their last character
words = ["banana", "apple", "cherry", "date", "kiwi"]
by_last = sorted(words, key=lambda w : w[-1])
print("By last character:", by_last)
# Sort a list of tuples — primary by age, secondary by name
people = [("Priya", 25), ("Arjun", 25), ("Kiran", 22), ("Sneha", 22)]
ordered = sorted(people, key=lambda p : (p[1], p[0]))
print("By age then name:", ordered)
# Use max() with a key lambda to find the longest word
words2 = ["cat", "elephant", "dog", "rhinoceros", "ant"]
longest = max(words2, key=lambda w : len(w))
print("Longest word:", longest)
# Use min() to find the cheapest product
inventory = [("Pen", 15), ("Bag", 850), ("Notebook", 120)]
cheapest = min(inventory, key=lambda item : item[1])
print("Cheapest:", cheapest)
key=lambda p : (p[1], p[0])— returning a tuple as the key sorts by the first element first, then uses the second as a tiebreaker. This is the standard multi-field sort pattern.max()andmin()also accept akeylambda — powerful for finding the item with the highest or lowest value of any field.
When to Use Lambda vs When to Use def
Knowing the right tool for the job is what separates good code from great code. Here is a clear framework:
| Use Lambda when | Use def when |
|---|---|
| Logic fits in one expression | Logic needs multiple lines or statements |
| Used inline as an argument | Function is called by name in many places |
| No documentation needed | A docstring would help other developers |
| Quick transformation or condition | Complex branching or error handling needed |
| Used once and discarded | Function needs to be reused across the codebase |
# Good use of lambda — short, inline, one expression
nums = [5, 2, 8, 1, 9, 3]
nums.sort(key=lambda n : n)
print("Sorted:", nums)
# Bad use of lambda — too complex, hard to read
# Don't do this:
# process = lambda x : x * 2 if x > 0 else (x + 10 if x > -5 else abs(x))
# Better as a def function with clear logic:
def process(x):
"""Transforms x based on its value range."""
if x > 0:
return x * 2
elif x > -5:
return x + 10
else:
return abs(x)
for val in [3, -2, -8]:
print(f"process({val}) = {process(val)}")
- A good test: can you read the lambda out loud in one natural sentence? If yes, use it. If not, use a
def. - Python's own style guide (PEP 8) discourages assigning a lambda to a variable — if you are giving it a name, just use
definstead.
Common Lambda Mistakes
# MISTAKE 1: Using return inside a lambda
# bad_f = lambda x : return x * 2 # SyntaxError!
# Fix: just write the expression
good_f = lambda x : x * 2
# MISTAKE 2: Forgetting list() around map/filter
nums = [1, 2, 3]
result = map(lambda x : x * 2, nums)
print(type(result)) # — NOT a list yet
print(list(result)) # [2, 4, 6] — now it is a list
# MISTAKE 3: Trying to write multi-line logic in a lambda
# This does NOT work:
# f = lambda x :
# y = x * 2
# return y
# Use def instead
# MISTAKE 4: Reassigning a consumed map/filter object
m = map(lambda x : x * 2, [1, 2, 3])
print(list(m)) # [2, 4, 6] — works
print(list(m)) # [] — empty! map objects are consumed once
# Fix: assign list() immediately
m2 = list(map(lambda x : x * 2, [1, 2, 3]))
print(m2) # [2, 4, 6]
print(m2) # [2, 4, 6] — works every time
map()andfilter()return lazy iterators — they are consumed once. Always wrap inlist()immediately if you need to use the result more than once.- You cannot use
return, assignment, or multiple statements inside a lambda. If you need any of those, usedef.
Real World Example — Full Data Processing Pipeline
This example builds a complete pipeline using filter(), map(), sorted(), and reduce() with lambdas — the kind of data transformation you would write in a backend service, data engineering script, or analytics tool.
from functools import reduce
# Raw order data from an e-commerce system
orders = [
{"id": "A001", "product": "Laptop", "qty": 1, "price": 75000, "status": "paid"},
{"id": "A002", "product": "Mouse", "qty": 3, "price": 599, "status": "pending"},
{"id": "A003", "product": "Monitor", "qty": 2, "price": 18000, "status": "paid"},
{"id": "A004", "product": "Keyboard", "qty": 0, "price": 1200, "status": "cancelled"},
{"id": "A005", "product": "Webcam", "qty": 5, "price": 2200, "status": "paid"},
{"id": "A006", "product": "Headset", "qty": 2, "price": 1800, "status": "pending"},
]
# Step 1: Keep only paid orders with quantity > 0
paid_orders = list(filter(
lambda o : o["status"] == "paid" and o["qty"] > 0,
orders
))
# Step 2: Add a "total" field to each paid order
with_total = list(map(
lambda o : {**o, "total": o["qty"] * o["price"]},
paid_orders
))
# Step 3: Sort by total value — highest first
ranked = sorted(with_total, key=lambda o : o["total"], reverse=True)
# Step 4: Calculate the grand total using reduce
grand_total = reduce(lambda acc, o : acc + o["total"], ranked, 0)
# Display the results
print(f"{'ID':<6} {'Product':<12} {'Qty':>4} {'Price':>8} {'Total':>10}")
print("-" * 44)
for o in ranked:
print(f"{o['id']:<6} {o['product']:<12} {o['qty']:>4} {o['price']:>8} {o['total']:>10}")
print("-" * 44)
print(f"{'Grand Total':>34}: {grand_total:>10}")
- filter — removes cancelled orders and orders with zero quantity. 3 of 6 orders survive.
- map —
{**o, "total": ...}copies all existing fields and adds a new"total"key without modifying the original dictionaries. - sorted — ranks orders by total value so the most valuable appears first.
- reduce — the third argument
0is the initial accumulator value — important when the list might be empty. - This four-step pipeline is the backbone of real data processing: filter → transform → sort → aggregate.
Quick Reference Table
| Concept | Syntax | What It Does |
|---|---|---|
| Basic lambda | lambda x : x * 2 | One-line anonymous function |
| Two parameters | lambda a, b : a + b | Accepts multiple inputs |
| No parameters | lambda : "hello" | Returns a fixed value |
| With map() | list(map(lambda x : x*2, lst)) | Transforms every item |
| With filter() | list(filter(lambda x : x>5, lst)) | Keeps items where True |
| With sorted() | sorted(lst, key=lambda x : x[1]) | Sorts by custom field |
| With reduce() | reduce(lambda a, b : a+b, lst) | Folds list into one value |
| Conditional | lambda x : "Y" if x>0 else "N" | Inline if/else |
| Multi-key sort | key=lambda p : (p[1], p[0]) | Sort by multiple fields |
| Immediately invoked | (lambda x : x+1)(5) | Define and call at once |
Practice
What keyword is used to create a lambda function?
Which built-in function applies a lambda to every item in a list?
Which built-in function keeps only items where the lambda returns True?
When using sorted() with a lambda, which parameter do you pass the lambda to?
What does (lambda a, b : a * b)(5, 5) return?
From which module must you import reduce() in Python 3?
Quick Quiz
What does "anonymous" mean when describing a lambda function?
What does list(map(lambda x : x * 2, [1, 2, 3])) return?
What does list(filter(lambda x : x % 2 == 0, [1, 2, 3, 4, 5])) return?
What does reduce(lambda a, b : a * b, [1, 2, 3, 4, 5]) return?
When should you use a regular def function instead of a lambda?
What does list(m) print the second time if m = map(lambda x : x*2, [1,2,3])?