Functional Programming in Python
Use ← → arrow keys or Space to navigate | Press F for fullscreen
Writing programs as transformations from inputs to outputs
Describe each step and update state along the way.
prices = [10, 20, 30]
discounted = []
for price in prices:
new_price = price * 0.9
discounted.append(new_price)
Describe the transformation and produce a new value.
prices = [10, 20, 30]
discounted = [
price * 0.9
for price in prices
]
Purity, immutability, functions as values, lambdas, decorators, comprehensions
# Pure
def add_tax(price, rate):
return price * (1 + rate)
# Not pure: depends on global state
tax_rate = 0.07
def add_tax_global(price):
return price * (1 + tax_rate)
Functional code often returns a new value instead of changing an existing one.
def add_item(items, new_item):
return items + [new_item]
cart = ["book", "pen"]
new_cart = add_item(cart, "notebook")
print(cart) # ['book', 'pen']
print(new_cart) # ['book', 'pen', 'notebook']
map, filter, decorators, callbacks, and custom sorting.
def square(x):
return x * x
def apply(func, values):
return [func(v) for v in values]
nums = [1, 2, 3, 4]
print(apply(square, nums))
# [1, 4, 9, 16]
A lambda is a small anonymous function for simple expressions.
| Use case | Example |
|---|---|
| Sort key | key=lambda s: len(s) |
| Quick transform | lambda x: x * 2 |
| Pair key | lambda item: item[1] |
def.
names = ["Ada", "Grace", "Linus"]
by_length = sorted(
names,
key=lambda name: len(name)
)
print(by_length)
# ['Ada', 'Grace', 'Linus']
nums = [1, 2, 3, 4, 5]
squares = list(map(lambda n: n*n, nums))
evens = list(filter(lambda n: n % 2 == 0, nums))
nums = [1, 2, 3, 4, 5]
squares = [n*n for n in nums]
evens = [n for n in nums if n % 2 == 0]
map and filter with lambdas.
A higher-order function works with other functions.
def make_multiplier(factor):
def multiply(x):
return x * factor
return multiply
double = make_multiplier(2)
triple = make_multiplier(3)
print(double(10)) # 20
print(triple(10)) # 30
@decorator syntax replaces manual wrapping.def announce(func):
def wrapper(*args, **kwargs):
print(f"Calling {func.__name__}")
return func(*args, **kwargs)
return wrapper
@announce
def greet(name):
return f"Hello, {name}"
print(greet("Ada"))
Recursion, context managers, and practical tools from functools
def factorial(n):
if n == 0: # base case
return 1
return n * factorial(n - 1)
print(factorial(5)) # 120
A context manager handles setup and cleanup around a block of code.
from contextlib import contextmanager
@contextmanager
def section(name):
print(f"Start {name}")
try:
yield
finally:
print(f"End {name}")
with section("demo"):
print("working")
functools Module| Tool | Use |
|---|---|
reduce | Combine many values into one |
partial | Pre-fill some function arguments |
lru_cache | Memoize expensive function calls |
from functools import reduce, partial, lru_cache
total = reduce(lambda a, b: a + b, [1, 2, 3])
def power(base, exp):
return base ** exp
square = partial(power, exp=2)
@lru_cache
def fib(n):
if n < 2:
return n
return fib(n-1) + fib(n-2)
| Concept | Key syntax / notes |
|---|---|
| Pure function | No side effects; depends only on arguments |
| Immutable update | Return a new value instead of mutating the original |
| Lambda | lambda args: expression |
| Map/filter | map(func, xs), filter(pred, xs) |
| Comprehension | [expr for item in xs if condition] |
| Decorator | @decorator wraps a function |
| Recursion | Base case plus recursive case |
| Context manager | with manager: handles setup and cleanup |
| functools | reduce, partial, lru_cache |
Next up: DSA and algorithms
pure functions · lambdas · decorators · recursion · functools