[Python-ideas] Add nullifier argument to functools.reduce?
Steven D'Aprano
steve at pearwood.info
Sun Aug 24 03:53:26 CEST 2014
On Sat, Aug 23, 2014 at 11:43:42AM -0700, David Mertz wrote:
> def reduce_with_attractor(func, it, start=None, end_if=None):
> it = iter(it)
> start = start if start!=None else it.__next__()
> return list(takewhile(lambda x: x!=end_if,
> accumulate(chain([start],it), func)))[-1]
A couple of points:
- Don't use it.__next__(), use the built-in next(it).
- To match the behaviour of reduce, you need to catch the StopIteration
and raise TypeError.
- Your implementation eagerly generates a potentially enormous list of
intermediate results, which strikes me as somewhat unfortunate for a
functional tool like reduce. In other words, for some inputs, this is
going to perform like a dog, generating a HUGE list up front, then
throwing it all away except for the final value.
> This gives you the accumulation up-to-but-not-including the attractor. I
> guess the OP wanted to return the attractor itself (although that seems
> slightly less useful to me).
Not really. His use-case seems to be to short-cut a lot of unnecessary
calculations, e.g. suppose you write product() as reduce(operator.mul,
iterable). In the event that the product reaches zero, you can[1]
short-circuit the rest of the iterable and just return 0:
product([1, 2, 3, 0] + [4]*1000000)
ought to reduce 0, not 6, and the intent is for it to do so *quickly*,
ignoring the 4s at the end of the list.
[1] Actually you can't. 0 is no longer an attractor in the presence of
INF or NAN.
--
Steven
More information about the Python-ideas
mailing list