map/filter/reduce pipelines vs comprehensions
map(f, it) applies f to each item, filter(pred, it) keeps items where pred is truthy, and functools.reduce(f, it, initial) folds a sequence into a single value by repeatedly applying a two-argument function. In Python 3, map and filter return lazy iterators (not lists), and reduce lives in functools because it was removed from the builtins in 3.0. Chained, they express a classic functional pipeline: filter, then transform, then aggregate.
When I choose which: for the same filter-plus-transform, a comprehension or generator expression is more Pythonic because it avoids lambdas, reads left to right, and supports conditions and nesting naturally ([f(x) for x in xs if p(x)]). map is still a good fit when the function already exists, especially a C-implemented one like str, int or len (map(int, parts)), or when mapping over several iterables in parallel, and it can be a little faster there because no Python-level lambda is called per item. With a lambda, map and filter are typically no faster than a comprehension, and readability suffers.
reduce is the one I use least, because most reductions already have a clearer name: sum, min, max, any, all, math.prod, str.join, and math.gcd with multiple arguments (3.9+). Legitimate uses are those with no builtin: function composition (above), merging a list of dicts or sets with an operator, or a custom fold with state. Always pass an initial value when the input may be empty, or you get a TypeError; and avoid reduce with string or list concatenation in a loop-like way because it creates quadratic work. Guido van Rossum famously argued for removing it from the builtins for readability reasons, and style guides typically favour explicit loops or builtins over complex reduce lambdas.
Other practical points: because map and filter are lazy, you must consume them (list(), for loop) and they are single-pass, like generators. For parallel work, multiprocessing.Pool.map and concurrent.futures.Executor.map have the same shape but require picklable functions, so lambdas fail there. The operator module (itemgetter, attrgetter, add, mul) and functools.partial replace many lambdas and are both faster and clearer.
0-2 years experience
2-5 years experience
5-8 years experience
8+ years experience