获取列表中各个部分的总和

时间:2019-06-18 09:23:31

标签: python list list-comprehension

我有一个列表[0, 1, 2, 3, 4, 5, 6],我将其部分加总为:

l = [0, 1, 2, 3, 4, 5, 6] -> 21

l = [1, 2, 3, 4, 5, 6] -> 21

l = [2, 3, 4, 5, 6] -> 20

l = [3, 4, 5, 6] -> 18

l = [4, 5, 6] -> 15

l = [5, 6] -> 11

l = [6] -> 6

l = [] -> 0

因此,我得到了列表各部分的相应总和:[21, 21, 20, 18, 15, 11, 6, 0]

我使用的代码是:

[sum(l[i:]) for i in range(len(l) + 1)]

但是,对于范围大于100000的列表,代码会明显放慢速度。

有人知道为什么以及如何对其进行优化吗?

3 个答案:

答案 0 :(得分:6)

为此,我建议使用itertools.accumulate(i recallnp.cumsum快),并反转一些列表以获取所需的输出:

>>> from itertools import accumulate
>>> lst = [0, 1, 2, 3, 4, 5, 6]
>>> list(accumulate(reversed(lst)))[::-1]
[21, 21, 20, 18, 15, 11, 6]

(如果需要,您可以在末尾添加0

答案 1 :(得分:6)

这可能有助于减少大列表的计算时间:

l = [0, 1, 2, 3, 4, 5, 6]
output = list(np.cumsum(l[::-1]))[::-1]+[0]

输出

[21, 21, 20, 18, 15, 11, 6, 0]

以下是四种不同方法对性能的比较,所有这些方法都具有相同的作用:

from timeit import timeit

def sum10(l):
    from itertools import accumulate
    return list(accumulate(reversed(l)))[::-1]+[0]

def sum11(l):
    from itertools import accumulate
    return list(accumulate(l[::-1]))[::-1]+[0]


def sum20(l):
    from numpy import cumsum
    return list(cumsum(l[::-1]))[::-1]+[0]

def sum21(l):
    from numpy import cumsum
    return list(cumsum(list(reversed(l))))[::-1]+[0]

l = list(range(1000000))
iter_0 = timeit(lambda: sum10(l), number=10)  #0.14102990700121154
iter_1 = timeit(lambda: sum11(l), number=10)  #0.1336850459993002
nump_0 = timeit(lambda: sum20(l), number=10)  #0.6019859320003889
nump_1 = timeit(lambda: sum21(l), number=10)  #0.3818727100006072

答案 2 :(得分:1)

据我所知,目前尚无干净的方法来处理列表推导。

此代码无需任何其他库即可工作:

def cumulative_sum(a):
  total= 0
  for item in a:
    total += item
    yield total

list(cumulative_sum(listname))

从Python 3.8开始,有一个新的operator可能会有所帮助:

[(x, total := total + x) for x in items]