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

Neil Girdhar mistersheik at gmail.com
Mon Apr 9 16:43:15 EDT 2018



On Friday, April 6, 2018 at 9:03:05 PM UTC-4, Raymond Hettinger wrote:
>
> > On Friday, April 6, 2018 at 8:14:30 AM UTC-7, Guido van Rossum wrote: 
> > On Fri, Apr 6, 2018 at 7:47 AM, Peter O'Connor <peter.ed... at gmail.com> 
> wrote: 
> >>   So some more humble proposals would be: 
> >> 
> >> 1) An initializer to itertools.accumulate 
> >> functools.reduce already has an initializer, I can't see any 
> controversy to adding an initializer to itertools.accumulate 
> > 
> > See if that's accepted in the bug tracker. 
>
> It did come-up once but was closed for a number reasons including lack of 
> use cases.  However, Peter's signal processing example does sound 
> interesting, so we could re-open the discussion. 
>
> For those who want to think through the pluses and minuses, I've put 
> together a Q&A as food for thought (see below).  Everybody's design 
> instincts are different -- I'm curious what you all think think about the 
> proposal. 
>
>
> Raymond 
>
> --------------------------------------------- 
>
> Q. Can it be done? 
> A. Yes, it wouldn't be hard. 
>
>         _sentinel = object() 
>
>         def accumulate(iterable, func=operator.add, start=_sentinel): 
>             it = iter(iterable) 
>             if start is _sentinel: 
>                 try: 
>                     total = next(it) 
>                 except StopIteration: 
>                     return 
>             else: 
>                 total = start 
>             yield total 
>             for element in it: 
>                 total = func(total, element) 
>                 yield total 
>
> Q. Do other languages do it? 
> A. Numpy, no. R, no. APL, no. Mathematica, no. Haskell, yes. 
>

Isn't numpy a yes?  
https://docs.scipy.org/doc/numpy/reference/generated/numpy.ufunc.accumulate.html

They definitely support it for add and multiply.  It's defined, but doesn't 
seem to work on custum ufuncs (the result of frompyfunc).
  

>
>     * 
> http://docs.scipy.org/doc/numpy/reference/generated/numpy.ufunc.accumulate.html 
>     * https://stat.ethz.ch/R-manual/R-devel/library/base/html/cumsum.html 
>     * http://microapl.com/apl/apl_concepts_chapter5.html 
>       \+ 1 2 3 4 5 
>       1 3 6 10 15 
>     * https://reference.wolfram.com/language/ref/Accumulate.html 
>     * https://www.haskell.org/hoogle/?hoogle=mapAccumL 
>
>
> Q. How much work for a person to do it currently? 
> A. Almost zero effort to write a simple helper function: 
>
>    myaccum = lambda it, func, start: accumulate(chain([start], it), func) 
>
>
> Q. How common is the need? 
> A. Rare. 
>
>
> Q. Which would be better, a simple for-loop or a customized itertool? 
> A. The itertool is shorter but more opaque (especially with respect 
>    to the argument order for the function call): 
>
>         result = [start] 
>         for x in iterable: 
>              y = func(result[-1], x) 
>              result.append(y) 
>
>     versus: 
>
>         result = list(accumulate(iterable, func, start=start)) 
>
>
> Q. How readable is the proposed code? 
> A. Look at the following code and ask yourself what it does: 
>
>         accumulate(range(4, 6), operator.mul, start=6) 
>
>    Now test your understanding: 
>
>         How many values are emitted? 
>         What is the first value emitted? 
>         Are the two sixes related? 
>         What is this code trying to accomplish? 
>
>
> Q. Are there potential surprises or oddities? 
> A. Is it readily apparent which of assertions will succeed? 
>
>         a1 = sum(range(10)) 
>         a2 = sum(range(10), 0) 
>         assert a1 == a2 
>
>         a3 = functools.reduce(operator.add, range(10)) 
>         a4 = functools.reduce(operator.add, range(10), 0) 
>         assert a3 == a4 
>
>         a4 = list(accumulate(range(10), operator.add)) 
>         a5 = list(accumulate(range(10), operator.add, start=0)) 
>         assert a5 == a6 
>
>
> Q. What did the Python 3.0 Whatsnew document have to say about reduce()? 
> A. "Removed reduce(). Use functools.reduce() if you really need it; 
> however, 99 percent of the time an explicit for loop is more readable." 
>
>
> Q. What would this look like in real code? 
> A. We have almost no real-world examples, but here is one from a 
> StackExchange post: 
>
>         def wsieve():       # wheel-sieve, by Will Ness.    
> ideone.com/mqO25A->0hIE89 
>             wh11 = [ 2,4,2,4,6,2,6,4,2,4,6,6, 2,6,4,2,6,4,6,8,4,2,4,2, 
>                      4,8,6,4,6,2,4,6,2,6,6,4, 2,4,6,2,6,4,2,4,2,10,2,10] 
>             cs = accumulate(cycle(wh11), start=11) 
>             yield( next( cs))       #   cf. ideone.com/WFv4f 
>             ps = wsieve()           #     
> codereview.stackexchange.com/q/92365/9064 
>             p = next(ps)            # 11 
>             psq = p*p               # 121 
>             D = dict( zip( accumulate(wh11, start=0), count(0)))   # start 
> from 
>             sieve = {} 
>             for c in cs: 
>                 if c in sieve: 
>                     wheel = sieve.pop(c) 
>                     for m in wheel: 
>                         if not m in sieve: 
>                             break 
>                     sieve[m] = wheel    # sieve[143] = wheel at 187 
>                 elif c < psq: 
>                     yield c 
>                 else:          # (c==psq) 
>                     # map (p*) (roll wh from p) = roll (wh*p) from (p*p) 
>                     x = [p*d for d in wh11] 
>                     i = D[ (p-11) % 210] 
>                     wheel = accumulate(cycle(x[i:] + x[:i]), start=psq) 
>                     p = next(ps) ; psq = p*p 
>                     next(wheel) ; m = next(wheel) 
>                     sieve[m] = wheel 
> _______________________________________________ 
> Python-ideas mailing list 
> Python... at python.org <javascript:> 
> https://mail.python.org/mailman/listinfo/python-ideas 
> Code of Conduct: http://python.org/psf/codeofconduct/ 
>
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://mail.python.org/pipermail/python-ideas/attachments/20180409/1e4522d6/attachment-0001.html>


More information about the Python-ideas mailing list