use*_*323 72 python sum list accumulate
time_interval = [4, 6, 12]
Run Code Online (Sandbox Code Playgroud)
我想总结数字[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
Run Code Online (Sandbox Code Playgroud)
ask*_*han 98
如果你正在使用这样的数组做很多数值工作,我建议numpy,它带有累积和函数cumsum:
import numpy as np
a = [4,6,12]
np.cumsum(a)
#array([4, 10, 22])
Run Code Online (Sandbox Code Playgroud)
对于这种事情,Numpy通常比纯python更快,与@ Ashwiniaccumu相比:
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
Run Code Online (Sandbox Code Playgroud)
但是当然如果它是唯一一个你会使用numpy的地方,它可能不值得依赖它.
Ash*_*ary 81
在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]
Run Code Online (Sandbox Code Playgroud)
在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]
Run Code Online (Sandbox Code Playgroud)
won*_*ice 18
看吧:
a = [4, 6, 12]
reduce(lambda c, x: c + [c[-1] + x], a, [0])[1:]
Run Code Online (Sandbox Code Playgroud)
将输出(如预期):
[4, 10, 22]
Run Code Online (Sandbox Code Playgroud)
小智 16
试试这个
itertools.accumulate()功能。
import itertools
list(itertools.accumulate([1,2,3,4,5]))
# [1, 3, 6, 10, 15]
Run Code Online (Sandbox Code Playgroud)
Chr*_*nds 13
我用Python 3.4做了前两个答案的基准测试,我发现itertools.accumulate它比numpy.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
Run Code Online (Sandbox Code Playgroud)
对于较长的列表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
Run Code Online (Sandbox Code Playgroud)
如果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
Run Code Online (Sandbox Code Playgroud)
如果你把导入放在两个函数之外但仍然返回一个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
Run Code Online (Sandbox Code Playgroud)
Ste*_*ski 12
PEP 572(Python 3.8 中的新功能)中的赋值表达式提供了另一种解决此问题的方法:
time_interval = [4, 6, 12]
total_time = 0
cum_time = [total_time := total_time + t for t in time_interval]
Run Code Online (Sandbox Code Playgroud)
您可以使用简单的for循环在线性时间内计算累积总和列表:
def csum(lst):
s = lst.copy()
for i in range(1, len(s)):
s[i] += s[i-1]
return s
time_interval = [4, 6, 12]
print(csum(time_interval)) # [4, 10, 22]
Run Code Online (Sandbox Code Playgroud)
标准库itertools.accumulate可能是一个更快的替代方案(因为它是用 C 实现的):
from itertools import accumulate
time_interval = [4, 6, 12]
print(list(accumulate(time_interval))) # [4, 10, 22]
Run Code Online (Sandbox Code Playgroud)
从python 3.8开始,可以使用赋值表达式,所以这样的事情变得更容易实现
nums = list(range(1, 10))
print(f'array: {nums}')
v = 0
cumsum = [v := v + n for n in nums]
print(f'cumsum: {cumsum}')
Run Code Online (Sandbox Code Playgroud)
产生
array: [1, 2, 3, 4, 5, 6, 7, 8, 9]
cumsum: [1, 3, 6, 10, 15, 21, 28, 36, 45]
Run Code Online (Sandbox Code Playgroud)
可以应用相同的技术来查找乘积、平均值等。
p = 1
cumprod = [p := p * n for n in nums]
print(f'cumprod: {cumprod}')
s = 0
c = 0
cumavg = [(s := s + n) / (c := c + 1) for n in nums]
print(f'cumavg: {cumavg}')
Run Code Online (Sandbox Code Playgroud)
结果是
cumprod: [1, 2, 6, 24, 120, 720, 5040, 40320, 362880]
cumavg: [1.0, 1.5, 2.0, 2.5, 3.0, 3.5, 4.0, 4.5, 5.0]
Run Code Online (Sandbox Code Playgroud)