运行总和的列表推导式

29 投票
14 回答
44029 浏览
提问于 2025-04-16 02:29

我想从一串数字中得到一个累计总和。

为了演示,我先用 range 创建一个连续的数字列表。

a = range(20)

runningTotal = []
for n in range(len(a)):
    new = runningTotal[n-1] + a[n] if n > 0 else a[n]
    runningTotal.append(new)

# This one is a syntax error
# runningTotal = [a[n] for n in range(len(a)) if n == 0 else runningTotal[n-1] + a[n]]

for i in zip(a, runningTotal):
    print "{0:>3}{1:>5}".format(*i)

这样就得到了

  0    0
  1    1
  2    3
  3    6
  4   10
  5   15
  6   21
  7   28
  8   36
  9   45
 10   55
 11   66
 12   78
 13   91
 14  105
 15  120
 16  136
 17  153
 18  171
 19  190

如你所见,我先初始化了一个空列表 [],然后在每次循环中用 append() 方法把数字加进去。有没有更简洁的方法,比如用列表推导式?

14 个回答

28

如果你能使用 numpy 这个库,它里面有一个叫 cumsum 的内置函数,可以完成这个功能。

import numpy as np
tot = np.cumsum(a)  # returns a np.ndarray
tot = list(tot)     # if you prefer a list
30

列表推导式没有一个好的(干净、可移植的)方法来引用它正在构建的那个列表。一个不错且优雅的做法是使用生成器来完成这个任务:

def running_sum(a):
  tot = 0
  for item in a:
    tot += item
    yield tot

当然,如果你想把结果变成一个列表,可以使用 list(running_sum(a))

10

使用 itertools.accumulate()。下面是一个例子:

from itertools import accumulate

a = range(20)
runningTotals = list(accumulate(a))

for i in zip(a, runningTotals):
    print "{0:>3}{1:>5}".format(*i)

这个方法只适用于Python 3。如果你在用Python 2,可以在more-itertools这个包里找到类似的功能。

撰写回答