如何查找列表中的累计数字总和?

time_interval = [4, 6, 12] 

我想总结一下[4, 4+6, 4+6+12]这样的数字来得到列表t = [4, 10, 22]

我尝试了以下内容:

 for i in time_interval: t1 = time_interval[0] t2 = time_interval[1] + t1 t3 = time_interval[2] + t2 print(t1, t2, t3) 4 10 22 4 10 22 4 10 22 

如果你正在用这样的数组做很多数值工作,我会建议numpy ,它带有一个累积求和函数cumsum

 import numpy as np a = [4,6,12] np.cumsum(a) #array([4, 10, 22]) 

对于这种事情,Numpy通常比纯Python更快,相比之下, @ Ashwini的accumu

 In [136]: timeit list(accumu(range(1000))) 10000 loops, best of 3: 161 us per loop In [137]: timeit list(accumu(xrange(1000))) 10000 loops, best of 3: 147 us per loop In [138]: timeit np.cumsum(np.arange(1000)) 100000 loops, best of 3: 10.1 us per loop 

但是,当然,如果它是唯一使用numpy的地方,可能不值得依赖它。

在Python 2中,您可以像这样定义自己的生成器函数:

 def accumu(lis): total = 0 for x in lis: total += x yield total In [4]: list(accumu([4,6,12])) Out[4]: [4, 10, 22] 

在Python 3.2+中,你可以使用itertools.accumulate()

 In [1]: lis = [4,6,12] In [2]: from itertools import accumulate In [3]: list(accumulate(lis)) Out[3]: [4, 10, 22] 

看吧:

 a = [4, 6, 12] reduce(lambda c, x: c + [c[-1] + x], a, [0])[1:] 

将输出(如预期):

 [4, 10, 22] 

我用Python 3.4对前两个答案做了一个基准numpy.cumsum在很多情况下我发现itertools.accumulatenumpy.cumsum要快,通常要快得多。 然而,正如您从评论中看到的那样,情况可能并非总是如此,并且很难详尽地探索所有选项。 (如果您有进一步的基准测试结果,请随意添加评论或编辑此文章。)

一些时间…

对于短名单accumulate约4倍的速度:

 from timeit import timeit def sum1(l): from itertools import accumulate return list(accumulate(l)) def sum2(l): from numpy import cumsum return list(cumsum(l)) l = [1, 2, 3, 4, 5] timeit(lambda: sum1(l), number=100000) # 0.4243644131347537 timeit(lambda: sum2(l), number=100000) # 1.7077815784141421 

对于更长的列表, accumulate速度大约快3倍:

 l = [1, 2, 3, 4, 5]*1000 timeit(lambda: sum1(l), number=100000) # 19.174508565105498 timeit(lambda: sum2(l), number=100000) # 61.871223849244416 

如果numpy array没有强制转换为list ,那么accumulate速度仍然快了2倍:

 from timeit import timeit def sum1(l): from itertools import accumulate return list(accumulate(l)) def sum2(l): from numpy import cumsum return cumsum(l) l = [1, 2, 3, 4, 5]*1000 print(timeit(lambda: sum1(l), number=100000)) # 19.18597290944308 print(timeit(lambda: sum2(l), number=100000)) # 37.759664884768426 

如果你把这两个函数的输入放在外面,并且仍然返回一个numpy array ,那么accumulate仍然快了2倍:

 from timeit import timeit from itertools import accumulate from numpy import cumsum def sum1(l): return list(accumulate(l)) def sum2(l): return cumsum(l) l = [1, 2, 3, 4, 5]*1000 timeit(lambda: sum1(l), number=100000) # 19.042188624851406 timeit(lambda: sum2(l), number=100000) # 35.17324400227517 
 values = [4, 6, 12] total = 0 sums = [] for v in values: total = total + v sums.append(total) print 'Values: ', values print 'Sums: ', sums 

运行这个代码给出

 Values: [4, 6, 12] Sums: [4, 10, 22] 

首先,你需要一个子序列的运行列表:

 subseqs = (seq[:i] for i in range(1, len(seq)+1)) 

那么你只需要对每个子序列sum

 sums = [sum(subseq) for subseq in subseqs] 

(这不是最有效的方法,因为你要重复添加所有的前缀,但是对于大多数用例来说这可能并不重要,如果你不必考虑运行总数。)

如果您使用的是Python 3.2或更新的版本,则可以使用itertools.accumulate为您完成:

 sums = itertools.accumulate(seq) 

如果您使用的是3.1或更早的版本,您可以直接从文档中复制“等效”源代码(除了将其更改为2.5以及更早版本之后,将next(it)更改为it.next() )。

尝试这个:

 result = [] acc = 0 for i in time_interval: acc += i result.append(acc) 
 lst = [4,6,12] [sum(lst[:i+1]) for i in xrange(len(lst))] 

如果你正在寻找一个更有效的解决方案(更大的列表?)一个生成器可以是一个很好的电话(或者如果你真的关心性能只是使用numpy )。

 def gen(lst): acu = 0 for num in lst: yield num + acu acu += num print list(gen([4, 6, 12])) 
 In [42]: a = [4, 6, 12] In [43]: [sum(a[:i+1]) for i in xrange(len(a))] Out[43]: [4, 10, 22] 

这比上面的@Ashwini的小生成器生成器方法要小得多

 In [48]: %timeit list(accumu([4,6,12])) 100000 loops, best of 3: 2.63 us per loop In [49]: %timeit [sum(a[:i+1]) for i in xrange(len(a))] 100000 loops, best of 3: 2.46 us per loop 

对于更大的列表,发电机是确定的方式。 。 。

 In [50]: a = range(1000) In [51]: %timeit [sum(a[:i+1]) for i in xrange(len(a))] 100 loops, best of 3: 6.04 ms per loop In [52]: %timeit list(accumu(a)) 10000 loops, best of 3: 162 us per loop 

有点哈克,但似乎工作:

 def cumulative_sum(l): y = [0] def inc(n): y[0] += n return y[0] return [inc(x) for x in l] 

我确实认为内部函数可以修改在外部词法范围内声明的y ,但是这并不起作用,所以我们用结构修改来玩一些讨厌的黑客。 使用发生器可能更优雅。

不必使用Numpy,你可以直接在数组上循环,并沿途累积总和。 例如:

 a=range(10) i=1 while((i>0) & (i<10)): a[i]=a[i-1]+a[i] i=i+1 print a 

结果是:

 [0, 1, 3, 6, 10, 15, 21, 28, 36, 45] 
 def cummul_sum(list_arguement): cumm_sum_lst = [] cumm_val = 0 for eachitem in list_arguement: cumm_val += eachitem cumm_sum_lst.append(cumm_val) return cumm_sum_lst 

这将是Haskell风格:

 def wrand(vtlg): def helpf(lalt,lneu): if not lalt==[]: return helpf(lalt[1::],[lalt[0]+lneu[0]]+lneu) else: lneu.reverse() return lneu[1:] return helpf(vtlg,[0]) 

看看内置的sum()函数,它可能是你想要的。