4 ms·
Show me an example that uses `reduce` with a function other than sum/product that makes it clearer than the equivalent loop.
by reinhardt 10y ago
Show me an example that uses `reduce` with a function other than sum/product that makes it clearer than the equivalent loop.
- ramblenode 10y agoReduce doesn't have side effects, handles an empty collection, doesn't need to reference the index of the iterable, and self-documents the code as a fold. I find the last part nice because a loop or a Python comprehension would need to add a comment to explain what would otherwise be clear from the syntax. 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)
- dalke 10y agoI don't think that does what you think it does: >>> 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.
- reinhardt 10y ago> I don't think that does what you think it does: Heh, just proved my point. Reduce won't be missed.
- ramblenode 10y agoOuch, good catch! I can't think of a nice way to salvage reduce but these are some clever alternatives. Point anti-reduce.
- dalke 10y agoThis doesn't salvage it in any meaningful sense, but it does work: 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.