[issue25193] itertools.accumulate should have an optional initializer argument

Raymond Hettinger report at bugs.python.org
Sun Oct 25 18:42:58 EDT 2015


Raymond Hettinger added the comment:

> OTOH, none of those projects is natural fit for itertools,
> so changing itertools wouldn't help them directly.

Indeed, this may not be a natural fit for itertools problems.

As a side note, the itertools were designed to form the elements of "an iterator algebra" with itertools.chain() as the intended compose-operation, so the OPs original solution was the right way to do it.  

The main question is whether the current solution is common enough to warrant being made a little more convenient (saving 9 characters), and whether the resulting code reads well:

current:  accumulate(chain([10]), range(1,4), operator.mul)
proposed: accumulate(range(1,4), operator.mul, 10) 

The latter spelling saves 9 characters; however, to my eyes, the "10" isn't obvious about what it doing and its placement is odd (the order of execution is 10, 1, 2, 3 eventhough the argument order has the range(1,4) as the first argument and the "10" as the third-argument).  I don't think the proposed spelling is doing us any favors in terms of code clarity -- the current spelling with chain() is more versatile and makes it perfectly clear that the 10 happens before the 1,2,3.

The OP made reference to functools.reduce() for comparison but we should keep in mind that reduce() was banished to functools because Guido found it to be relatively unintelligible and thought most code would be clearer without it.

As an additional data point, I did a GitHub code search.  In the first 20 pages of the search results, I found only three examples.  The first example seems reasonable.  The second example was a toy demonstration of "generator and iterator towers".  And the third example was a olympiad toy puzzle problem.

Github Code Search
------------------
https://github.com/search?p=1&q=itertools.accumulate&ref=searchresults&type=Code&utf8=%E2%9C%93


Ex1:
----
def collect(seed, iterable):
    return it.accumulate(it.chain([seed], iterable))

Ex2:
----
for number, op, fac in itertools.chain(
     zip(itertools.accumulate(itertools.chain((nr,), range(2, 10)),
     operator.mul), itertools.repeat(" * "), range(2, 10)),

Ex3:
----
if sum(loop) % 2015 == 0 and not list(filter(test,
      itertools.accumulate(itertools.chain(start, loop)))):
          print(0)

----------

_______________________________________
Python tracker <report at bugs.python.org>
<http://bugs.python.org/issue25193>
_______________________________________


More information about the Python-bugs-list mailing list