Functional vs Imperative Style
The difference becomes clear with a simple example — doubling a list of numbers:Pure Functions
A pure function always returns the same output for the same input and produces no side effects (no writes to disk, no network calls, no changes to global state). Pure functions are trivial to test and safe to cache.map() — Transform Every Element
map(function, iterable) applies a function to every element of an iterable and returns a lazy iterator.
filter() — Keep Only Matching Elements
filter(function, iterable) returns a lazy iterator containing only elements for which the function returns True.
reduce() — Collapse a Collection to a Single Value
reduce(function, iterable) from functools applies a two-argument function cumulatively, reducing the sequence to a single result.
reduce() is powerful but can hurt readability when overused. For simple totals and products, Python’s built-in sum(), max(), and min() are clearer. Reserve reduce() for custom accumulation logic that has no built-in equivalent.functools.partial — Partial Application
functools.partial lets you pre-fill some arguments of a function, creating a new specialised version of it.
Chaining Operations
You can chainmap, filter, and other functional tools into a readable pipeline. For Python, combining comprehensions with sum/max/min is often the most readable approach.
When to Use Functional Style vs Comprehensions
Prefer map/filter when…
Prefer map/filter when…
- You already have a named function (avoids creating a redundant lambda):
list(map(str.upper, words)) - You are composing a pipeline with
partialor passing operations as arguments - You want lazy evaluation and will not materialise the full list
Prefer comprehensions when…
Prefer comprehensions when…
- You are writing a one-off transformation inline — comprehensions are more readable to most Python developers
- You need both filtering and transformation in one step
- The result needs to be a list, dict, or set specifically