[Python-ideas] Start argument for itertools.accumulate() [Was: Proposal: A Reduce-Map Comprehension and a "last" builtin]

Greg Ewing greg.ewing at canterbury.ac.nz
Sun Apr 8 19:49:57 EDT 2018


Raymond Hettinger wrote:
> For neither of those use case categories did I ever want an initial value and
> it would have been distracting to even had the option. For example, when
> doing a discounted cash flow analysis, I was taught to model the various
> flows as a single sequence of up and down arrows rather than thinking of the
> initial balance as a distinct concept¹

There's always an initial value, even if it's implicit.

The way accumulate() works can be thought of in two ways:

(1) The initial value is implicitly the identity of whatever
operation the function performs.

(2) The first item in the list is the initial value, and
the rest are items to be accumulated.

Both of these are somewhat dodgy, IMO. The first one works
only if the assumed identity is what you actually want, *and*
there is always at least one item to accumulate.

If those conditions don't hold, you need to insert the
initial value as the first item. But this is almost
certainly going to require extra code. The initial value
and the items are conceptually different things, and are
unlikely to start out in the same list together.

What's more, the first thing the implementation of
accumulate() does is extract the first item and treat it
differently from the rest. So your code goes out of its
way to insert the initial value, and then accumulate()
goes out of its way to pull it out again. Something
smells wrong about that.

As an example, suppose you have a list [1, 2, 3] and
you want to construct [], [1], [1, 2], [1, 2, 3].
To do that with accumulate() you need to write something
like:

    accumulate([[], 1, 2, 3], lambda x, y: x + [y])

The fact that the first element of the list doesn't even
have the same *type* as the rest should be a strong hint
that forcing them to occupy the same list is an
unnatural thing to do.

-- 
Greg







> 
> Because of this background, I was surprised to have the question ever come up
> at all (other than the symmetry argument that sum() has "start" so
> accumulate() must as well).
> 
> When writing itertools.accumulate(), I started by looking to see what other
> languages had done.  Since accumulate() is primarily a numerical tool, I
> expected that the experience of numeric-centric languages would have
> something to teach us.  My reasoning was that if the need hadn't arisen for
> APL, R, Numpy, Matlab², or Mathematica, perhaps it really was just noise.
> 
> My views may be dated though.  Looking at the wheel sieve and collatz glide
> record finder, I see something new, a desire to work with lazy, potentially
> infinite accumulations (something that iterators do well but almost never
> arises in the world of fixed-length sequences or cumulative probability
> distributions).
> 
> So I had been warming up to the idea, but got concerned that Nick could have
> had such a profoundly different idea about what the code should do.  That
> cooled my interest a bit, especially when thinking about two key questions,
> "Will it create more problems than it solves?" and "Will anyone actually use
> it?".
> 
> 
> 
> Raymond
> 
> 
> 
> 
> 
> 
> 
> ¹
> http://www.chegg.com/homework-help/questions-and-answers/solve-present-worth-cash-flow-shown-using-three-interest-factors-10-interest-compounded-an-q878034
> 
> 
> ² https://www.mathworks.com/help/matlab/ref/accumarray.html 
> _______________________________________________ Python-ideas mailing list 
> Python-ideas at python.org https://mail.python.org/mailman/listinfo/python-ideas
>  Code of Conduct: http://python.org/psf/codeofconduct/



More information about the Python-ideas mailing list