the_power_of_reduce
The power of reduce
-
reducewas a built-in function in Python 2; moved tofunctoolsin Python 3. -
reduceapplies a binary function to items of an iterable to reduce them to a single value. -
Simplified implementation:
def reduce(function, iterable, initial_value): result = initial_value for value in iterable: result = function(result, value) return result>>> reduce(operator.add, range(10)) # 0+1+2+...+9 45# basically def sum(iterable, start=0): acc = start for elem in iterable: acc = acc + elem return acc
-
Lambda equivalents using
reduce:all = lambda iterable: reduce(operator.and_, iterable) any = lambda iterable: reduce(operator.or_, iterable) max_ = lambda a, b: a if a >= b else b max = lambda iterable: reduce(max_, iterable) min_ = lambda a, b: a if a <= b else b min = lambda iterable: reduce(min_, iterable) sum = lambda iterable: reduce(operator.add, iterable)
“Fun” or Far-Fetched Reductions
-
First/Last element:
reduce(lambda l, r: l, iterable) # first element reduce(lambda l, r: r, iterable) # last element -
Building tuples using
reduce:reduce(lambda t, v: t + (v,), range(10), ())
The Identity Element and reduce's Third Argument
-
Third argument = initializer; used when the iterable might be empty.
-
If omitted and iterable is empty →
TypeError. -
Identity element: a value that doesn’t affect the result of the reduction.
Examples:
- Addition → 0
- Multiplication → 1
all()→Trueany()→False
-
For
max/min:- Identity:
-infformax,infformin - These are not used automatically because of type compatibility issues (e.g., strings)
- Identity:
Reductions Without Identity Elements
- Some reductions (like “last element”) lack a neutral identity.
- Must handle empty iterables via conditionals or
try/except.
Example: Accessing Nested Dictionaries
d = {"one": {2: {"c": {4: 42}}}}
keys = ["one", 2, "c", 4]
reduce(dict.get, keys, d) # → 42
Example: Accessing Nested Class Attributes
class C: pass
c = C()
c.one = C()
c.one._2 = C()
c.one._2.c = C()
c.one._2.c._4 = 42
attrs = ["one", "_2", "c", "_4"]
reduce(getattr, attrs, c) # → 42