Show me an example that uses `reduce` with a function other than sum/product that makes it clearer than the equivalent loop.
Here's an alternative example where I think it makes sense (checking if the size of all elements in a collection are equal):
reduce(lambda a, b: len(a) == len(b), ls) >>> reduce(lambda a, b: len(a) == len(b), ["a", "b", "c"])
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
File "<stdin>", line 1, in <lambda>
TypeError: object of type 'bool' has no len()
It's trying to do len(len("a") == len("b")) == len("c"), which becomes len(True) == len("c"), and len(True) doesn't work.Some variations which do work are:
len(set(map(len, ls))) == 1
len(set(len(x) for x in ls)) == 1
all(len(ls[0]) == len(x) for x in ls)
len(min(ls, key=len)) == len(max(ls, key=len))
Append "if ls else True" to handle the empty list.Heh, just proved my point. Reduce won't be missed.
class EqualLengths:
def __init__(self, size):
self.size = size
def __nonzero__(self):
return True
def __repr__(self):
return "True"
def equal_lengths(a, b):
if isinstance(a, EqualLengths):
if a.size == len(b):
return a
return False
if a is False:
return a
n = len(a)
if n == len(b):
return EqualLengths(n)
return False
>>> reduce(equal_lengths, ["a", "b", "cc", "d"])
False
>>> reduce(equal_lengths, ["a", "b", "c", "d"])
True
However, I could do something similar with sum(): class SumEqual:
def __init__(self):
self.size = None
self.is_equal = True
def __add__(self, other):
if self.is_equal:
if self.size is None:
self.size = len(other)
else:
self.is_equal = (self.size == len(other))
return self
def __nonzero__(self):
return self.is_equal
def __repr__(self):
return repr(self.is_equal)
>>> sum(["a", "b", "cc", "d"], SumEqual())
False
>>> sum(["a", "b", "c", "d"], SumEqual())
True
and unlike the first case, this sum() solution will work when there are fewer than two items in the list.