I want to generate or return an append-accumulated list from a given list (or iterator). For a list like [1, 2, 3, 4]
, I would like to get, [1]
, [1, 2]
, [1, 2, 3]
and [1, 2, 3, 4]
. Like so:
>>> def my_accumulate(iterable):
... grow = []
... for each in iterable:
... grow.append(each)
... yield grow
...
>>> for x in my_accumulate(some_list):
... print x # or something more useful
...
[1]
[1, 2]
[1, 2, 3]
[1, 2, 3, 4]
This works but is there an operation I could use with itertools.accumulate
to facilitate this? (I'm on Python2 but the pure-python implementation/equivalent has been provided in the docs.)
Another problem I have with my_accumulate
is that it doesn't work well with list()
, it outputs the entire some_list
for each element in the list:
>>> my_accumulate(some_list)
<generator object my_accumulate at 0x0000000002EC3A68>
>>> list(my_accumulate(some_list))
[[1, 2, 3, 4], [1, 2, 3, 4], [1, 2, 3, 4], [1, 2, 3, 4]]
Option 1:
I wrote my own appending accumulator function to use with itertools.accumulate
but considering the LoC and final useful-ness, it seems like a waste of effort, with my_accumulate
being more useful, (though may fail in case of empty iterables and consumes more memory since grow
keeps growing):
>>> def app_acc(first, second):
... if isinstance(first, list):
... first.append(second)
... else:
... first = [first, second]
... return first
...
>>> for x in accumulate(some_list, app_acc):
... print x
...
1
[1, 2]
[1, 2, 3]
[1, 2, 3, 4]
>>> list(accumulate(some_list, app_acc)) # same problem again with list
[1, [1, 2, 3, 4], [1, 2, 3, 4], [1, 2, 3, 4]]
(and the first returned elem is not a list, just a single item)
Option 2: Figured it would be easier to just do incremental slicing but using the ugly iterate over list length method:
>>> for i in xrange(len(some_list)): # the ugly iterate over list length method
... print some_list[:i+1]
...
[1]
[1, 2]
[1, 2, 3]
[1, 2, 3, 4]
The easiest way to use accumulate
is to make each item in the iterable a list with a single item and then the default function works as expected:
from itertools import accumulate
acc = accumulate([el] for el in range(1, 5))
res = list(acc)
# [[1], [1, 2], [1, 2, 3], [1, 2, 3, 4]]
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With