[英]Cumulative sum with list comprehension
我有一個整數列表:
x = [3, 5, 2, 7]
我想創建一個新列表,其中第nth
元素是x
從0
到n-1
的元素總和。
這將導致:
y = [0, 3, 8, 10]
如何在不運行循環的情況下使用列表理解來做到這一點?
沒有循環和列表理解如何? 遺憾的是只有 Python 3:
>>> x = [3, 5, 2, 7]
>>> from itertools import accumulate
>>> [0] + list(accumulate(x[:-1]))
[0, 3, 8, 10]
更新:這是一個 O(n) 列表理解解決方案:
>>> s = [0]
>>> [s.append(s[0]+n) or s.pop(0) for n in x]
[0, 3, 8, 10]
但我只想表明,無需太多努力即可實現。 我認為accumulate
或 for 循環要好得多。
純列表推導,O(n) 時間和 O(1) 額外空間(即除了列表推導構建列表所需的空間之外)( 在線嘗試! ):
xs = [3, 5, 2, 7]
# Equivalent for-loop version:
ys = [y # ys = []
for s in [0] # s = 0
for x in xs # for x in xs:
for y in [s] # y = s
for s in [s + x]] # s = s + x
# ys.append(y)
print(ys)
我重命名為復數xs
和ys
以便我可以命名單個值x
和y
。 我s
是累積和,在更新s
之前我記得它是y
(因為你要求結果[0, 3, 8, 10]
而不是[3, 8, 10, 17]
)。
請注意,自 CPython 3.9 起,我for y in [s]
和for s in [s + x]
進行了優化,因此它們實際上不會構建和迭代單元素列表,而是像y = s
和s = s + x
一樣工作s = s + x
:
>>> import dis
>>> dis.dis('''ys = [y
... for s in [0]
... for x in xs
... for y in [s]
... for s in [s + x]]''')
...
4 16 LOAD_FAST 1 (s)
18 STORE_FAST 3 (y)
5 20 LOAD_FAST 1 (s)
22 LOAD_FAST 2 (x)
24 BINARY_ADD
26 STORE_FAST 1 (s)
...
如果您正在對列表進行計算,則使用 numpy 可能會更好:
import numpy as np
x = [3, 5, 2, 7]
print(np.cumsum([0]+x[:-1]).tolist())
[0, 3, 8, 10]
或者如果 0 無關緊要:
import numpy as np
x = np.array([3, 5, 2, 7])
print( x[:-1].cumsum())
[ 3 8 10]
或者如果你想要 0 則追加:
import numpy as np
x = np.array([3, 5, 2, 7])
out = np.array(0)
print(np.append(out, x[:-1].cumsum()))
[0 3 8 10]
無論你做什么,總會有一個循環,我會更擔心編寫高效的代碼而不是簡短的代碼。
僅使用 python2 常規 for 循環將是有效的:
x = [3, 5, 2, 7]
sm = 0
out = []
for ele in x:
out.append(sm)
sm += ele
print(out)
[0, 3, 8, 10]
x = [3, 5, 2, 7]
cumsumx=[sum(x[:i] for i in range(len(x))]
這提供了您所需要的:
x = [3, 5, 2, 7]
y = [sum(x[0:i]) for i,value in enumerate(x)]
[0, 3, 8, 10]
這是我剛剛發現的一個甜蜜的:
s = 0
cumsum = [(s:=s+i) for i in my_list]
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.