bad*_*ker 1 python list-comprehension list
我有一个清单,[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
Run Code Online (Sandbox Code Playgroud)
因此,我得到了列表各部分的相应总和: [21, 21, 20, 18, 15, 11, 6, 0]
我使用的代码是:
[sum(l[i:]) for i in range(len(l) + 1)]
但是,对于范围大于100000代码的列表,速度会大大降低。
知道为什么以及如何对其进行优化吗?
我建议itertools.accumulate这样做(我记得比更快np.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]
Run Code Online (Sandbox Code Playgroud)
(0如果需要,您可以简单地添加到末尾)
这可能有助于减少大列表的计算时间:
l = [0, 1, 2, 3, 4, 5, 6]
output = list(np.cumsum(l[::-1]))[::-1]+[0]
Run Code Online (Sandbox Code Playgroud)
输出:
[21, 21, 20, 18, 15, 11, 6, 0]
Run Code Online (Sandbox Code Playgroud)
这是四种不同方法的性能比较,所有这些方法都具有相同的作用:
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
Run Code Online (Sandbox Code Playgroud)