我想从给定列表(或迭代器)生成或返回追加累积列表。对于[1, 2, 3, 4]
这样的列表,我想得到[1]
,[1, 2]
,[1, 2, 3]
和[1, 2, 3, 4]
。像这样:
>>> 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]
这样可行,但是我可以使用itertools.accumulate
来实现此操作吗? (我在Python2上,但文档中提供了纯python实现/等效。)
我对my_accumulate
的另一个问题是它不能与list()
一起使用,它会为列表中的每个元素输出整个some_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]]
选项1:
我编写了自己的附加累加器函数以与itertools.accumulate
一起使用,但考虑到LoC和最终的实用性,似乎是浪费精力,my_accumulate
更有用,(虽然在迭代空的情况下可能会失败并且因grow
不断增长而消耗更多内存:
>>> 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]]
(第一个返回的elem不是列表,只是一个项目)
选项2:想象一下,使用丑陋的迭代超过列表长度方法更容易进行增量切片:
>>> 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]
答案 0 :(得分:8)
使用accumulate
的最简单方法是使iterable中的每个项目都包含一个项目,然后默认函数按预期工作:
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]]