Python

Functions And Functional Basics

Lambda Functions & map/filter/reduce

A lambda is a small, anonymous (unnamed) function defined in a single expression — no def, no name, no return keyword (the expression's value is returned automa

JrCodex·7 min read

Jr Codex Python Notes

Level: Intermediate Prerequisites: Chapter 5 Time to complete: ~20 minutes


Table of Contents

  1. What is a Lambda?
  2. Lambda vs a Named Function
  3. Where Lambdas Actually Get Used
  4. map()
  5. filter()
  6. functools.reduce()
  7. Comprehensions vs map/filter — Which to Prefer
  8. Summary & Next Steps

1. What is a Lambda?

A lambda is a small, anonymous (unnamed) function defined in a single expression — no def, no name, no return keyword (the expression's value is returned automatically).

square = lambda x: x ** 2
print(square(5))     # 25
 
add = lambda a, b: a + b
print(add(3, 4))       # 7
Lambda Anatomy
─────────────────────────────────────────
  lambda  x  :  x ** 2
     ↑     ↑        ↑
   keyword param   expression (implicitly returned)
─────────────────────────────────────────

Equivalent def version, for comparison:

def square(x):
    return x ** 2

A lambda is limited to a single expression — no statements, no multiple lines, no if/for blocks (though a ternary expression is allowed since it's still one expression):

classify = lambda n: "even" if n % 2 == 0 else "odd"
print(classify(4))     # "even"

2. Lambda vs a Named Function

lambdadef
Has a name?No (anonymous) — though you can assign it to a variableYes
BodySingle expression onlyAny number of statements
Docstring supportNoYes
Typical useShort, throwaway, passed inline to another functionAnything reused, tested, or non-trivial

Style guideline (PEP 8): don't assign a lambda to a name just to call it later — use def instead. Lambdas are meant to be used inline, right where they're needed.

# Discouraged — just use def instead
square = lambda x: x ** 2
 
# Preferred for anything with a name
def square(x):
    return x ** 2
 
# This is where lambdas actually shine — passed directly as an argument
sorted([3, 1, 2], key=lambda x: -x)     # inline, no name needed

3. Where Lambdas Actually Get Used

The most common real-world use is as a key function for sorting:

students = [
    {"name": "Alice", "grade": 85},
    {"name": "Bob", "grade": 92},
    {"name": "Charlie", "grade": 78},
]
 
# Sort by grade, descending
by_grade = sorted(students, key=lambda s: s["grade"], reverse=True)
for s in by_grade:
    print(s["name"], s["grade"])
# Bob 92
# Alice 85
# Charlie 78
 
# Sort tuples by their second element
pairs = [(1, "b"), (3, "a"), (2, "c")]
pairs.sort(key=lambda pair: pair[1])
print(pairs)      # [(3, 'a'), (1, 'b'), (2, 'c')]

4. map()

Applies a function to every item in an iterable, returning a lazy map object (similar to a generator — see Chapter 5).

numbers = [1, 2, 3, 4, 5]
 
doubled = map(lambda x: x * 2, numbers)
print(list(doubled))     # [2, 4, 6, 8, 10] — must convert to list to see all values
 
# map() also works with a regular named function
def celsius_to_fahrenheit(c):
    return c * 9/5 + 32
 
temps_c = [0, 20, 37, 100]
temps_f = list(map(celsius_to_fahrenheit, temps_c))
print(temps_f)      # [32.0, 68.0, 98.6, 212.0]

Equivalent list comprehension (usually the more Pythonic choice — see Section 7):

doubled = [x * 2 for x in numbers]

5. filter()

Keeps only the items for which a function returns True.

numbers = range(1, 11)
 
evens = filter(lambda x: x % 2 == 0, numbers)
print(list(evens))     # [2, 4, 6, 8, 10]
 
words = ["apple", "hi", "banana", "ok", "cherry"]
long_words = filter(lambda w: len(w) > 3, words)
print(list(long_words))    # ['apple', 'banana', 'cherry']

Equivalent list comprehension:

evens = [x for x in numbers if x % 2 == 0]

6. functools.reduce()

Combines all items in an iterable into a single cumulative value, by repeatedly applying a function to a running total and the next item.

from functools import reduce
 
numbers = [1, 2, 3, 4, 5]
 
total = reduce(lambda acc, x: acc + x, numbers)
print(total)     # 15
 
product = reduce(lambda acc, x: acc * x, numbers)
print(product)     # 120
 
# With an explicit starting value
total_plus_100 = reduce(lambda acc, x: acc + x, numbers, 100)
print(total_plus_100)     # 115
reduce() Step by Step — sum of [1, 2, 3, 4, 5]
─────────────────────────────────────────
  step 1: acc=1, x=2  → acc = 1 + 2 = 3
  step 2: acc=3, x=3  → acc = 3 + 3 = 6
  step 3: acc=6, x=4  → acc = 6 + 4 = 10
  step 4: acc=10, x=5 → acc = 10 + 5 = 15
  final result: 15
─────────────────────────────────────────

Unlike map/filter, reduce isn't a built-in — it lives in functools and needs an explicit import. Note also that for simple sums/products, Python's built-in sum() and math.prod() are clearer than reduce — save reduce for genuinely custom accumulation logic.


7. Comprehensions vs map/filter — Which to Prefer

numbers = [1, 2, 3, 4, 5]
 
# map + lambda
result1 = list(map(lambda x: x * 2, numbers))
 
# list comprehension — same result
result2 = [x * 2 for x in numbers]
 
# filter + lambda
result3 = list(filter(lambda x: x % 2 == 0, numbers))
 
# list comprehension — same result
result4 = [x for x in numbers if x % 2 == 0]

Python community convention (PEP 8 spirit): prefer comprehensions over map()/filter() with a lambda — they're generally considered more readable and Pythonic. Reach for map/filter mainly when:

  • You already have a named function (not a lambda) to pass in — map(str.upper, words) reads cleanly.
  • You're chaining functional operations in a style borrowed from other languages, and the team already favors that idiom.
ToolPrefer When
List/dict/set comprehensionDefault choice — most readable for transform/filter
map() / filter()You already have a named function handy, no lambda needed
functools.reduce()Genuine custom accumulation — otherwise use sum(), max(), etc.

8. Summary & Next Steps

Key Takeaways

  • A lambda is a single-expression, unnamed function — ideal for short, inline use (like a sort key), not for anything you'd want to name and reuse.
  • map(func, iterable) transforms every item; filter(func, iterable) keeps items where func returns True. Both return lazy iterators — wrap in list() to see all results.
  • functools.reduce(func, iterable) collapses an iterable into a single accumulated value.
  • Comprehensions are generally preferred over map/filter + lambda for readability — reserve lambdas for cases like sort keys where naming a function would be overkill.

Module 2 Complete — Next Module

You now know how to package logic into functions, control their arguments and scope, and use Python's functional tools (comprehensions, lambda, map/filter/reduce). Module 3 shifts to organizing code across files and handling the real world — modules, file I/O, and errors.

Concept Check

  1. Why can't a lambda contain a for loop or multiple statements?
  2. Rewrite list(filter(lambda x: x > 0, numbers)) as a list comprehension.
  3. What does reduce(lambda acc, x: acc + x, [1,2,3], 100) return, and why does the 100 matter?

Next Chapter

Module 3: Modules, Data & Errors


Jr Codex — 1-on-1 Personalized Coaching | Back to Module Index