Python Story

Chapter #4 – Operations

functions, lambdas, decorators, comprehensions, generators

4.0 Prologue

This chapter covers the ways Python transforms data: function definition and calling conventions, anonymous functions, decorators for cross-cutting behavior, comprehensions for concise collection building, and generators for lazy evaluation.

4.1 Functions

Functions are first-class objects: they can be stored in variables, passed as arguments, and returned from other functions. Define them with def: def power(base: float, exp: int = 2) -> float: return base ** exp power(3) # 9.0 power(2, 10) # 1024.0 power(base=5) # 25.0 — keyword argument Positional-only parameters (before /) and keyword-only parameters (after *) give fine control over the calling convention: def strict(pos_only, /, normal, *, kwd_only): ...

4.2 Variadic Arguments

*args collects extra positional arguments into a tuple; **kwargs collects extra keyword arguments into a dict: def report(title: str, *items: str, sep: str = ", ") -> str: return title + ": " + sep.join(items) report("Colors", "red", "green", "blue") # Colors: red, green, blue The splat operators unpack sequences and mappings at call sites: func(*lst, **dct)

4.3 Lambda Expressions

A lambda is a single-expression anonymous function. Use them for short callbacks where a full def would be verbose: square = lambda x: x * x pairs = [(1, 'b'), (3, 'a'), (2, 'c')] pairs.sort(key=lambda p: p[0]) # sort by first element Lambdas are limited to a single expression; prefer named functions for anything more complex.

4.4 Closures

A function defined inside another function closes over the enclosing scope's variables, capturing them by reference: def make_adder(n: int): def adder(x: int) -> int: return x + n # n is captured from make_adder's scope return adder add5 = make_adder(5) print(add5(3)) # 8 Use nonlocal to rebind an enclosing variable from inside the inner function.

4.5 Decorators

A decorator is a callable that wraps a function (or class) to add behavior. The @name syntax is shorthand for func = name(func): import time, functools def timed(func): @functools.wraps(func) def wrapper(*args, **kwargs): start = time.perf_counter() result = func(*args, **kwargs) elapsed = time.perf_counter() - start print(f"{func.__name__} took {elapsed:.4f}s") return result return wrapper @timed def slow_sum(n: int) -> int: return sum(range(n)) slow_sum(1_000_000) Parameterized decorators add an extra layer: the outermost callable receives the parameters and returns the actual decorator. Standard library decorators:
  • @functools.lru_cache(maxsize=128) — memoization
  • @functools.cached_property — lazy attribute computed once
  • @staticmethod, @classmethod, @property
  • @dataclasses.dataclass — auto-generate class boilerplate

4.6 Comprehensions

Comprehensions build collections concisely and are generally faster than equivalent for loops: # list comprehension evens = [x for x in range(20) if x % 2 == 0] # dict comprehension word_len = {w: len(w) for w in ["apple", "fig", "banana"]} # set comprehension unique_lens = {len(w) for w in ["hi", "hello", "hey"]} # nested comprehension — flatten a matrix matrix = [[1, 2], [3, 4], [5, 6]] flat = [n for row in matrix for n in row] # [1, 2, 3, 4, 5, 6]

4.7 Generators

A generator function uses yield to produce values one at a time, suspending between yields. This enables memory-efficient pipelines over large or infinite sequences: def fibonacci(): a, b = 0, 1 while True: yield a a, b = b, a + b fib = fibonacci() print([next(fib) for _ in range(8)]) # [0, 1, 1, 2, 3, 5, 8, 13] Generator expressions use () syntax and are consumed once: total = sum(x*x for x in range(10**6)) yield from delegates to a sub-generator, enabling generator composition without manual forwarding loops.

4.8 Epilogue

This chapter covered Python's function model: calling conventions, closures, decorators, comprehensions, and generators. The next chapter applies these ideas inside classes.

4.9 References

Lambda expressions — python.org
Generators — python.org
PEP 289 — Generator Expressions
Decorators — Real Python