จะหาผลรวมของตัวเลขในรายการได้อย่างไร?


93
time_interval = [4, 6, 12]

ฉันต้องการที่จะสรุปตัวเลขที่ชอบในการสั่งซื้อที่จะได้รับรายชื่อ[4, 4+6, 4+6+12]t = [4, 10, 22]

ฉันลองทำสิ่งต่อไปนี้:

t1 = time_interval[0]
t2 = time_interval[1] + t1
t3 = time_interval[2] + t2
print(t1, t2, t3)  # -> 4 10 22

คำตอบ:


128

หากคุณกำลังทำงานเชิงตัวเลขกับอาร์เรย์เช่นนี้ฉันขอแนะนำnumpyซึ่งมาพร้อมกับฟังก์ชันผลรวมสะสมcumsum:

import numpy as np

a = [4,6,12]

np.cumsum(a)
#array([4, 10, 22])

Numpy มักจะเร็วกว่า python บริสุทธิ์สำหรับสิ่งประเภทนี้ดูเปรียบเทียบกับ@ Ashwini'saccumu :

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

แต่แน่นอนว่าถ้าเป็นที่เดียวที่คุณจะใช้มันอาจไม่คุ้มค่าที่จะต้องพึ่งพามัน


3
ซึ่งควรมีnp.cumsunกรณีที่ขึ้นต้นด้วยรายการเพื่อพิจารณาเวลาในการแปลง
hpaulj

3
@hpaulj จุดที่ดีสำหรับผู้ที่เริ่มต้นจาก (หรือเล็งบริการ) ฉันจะไม่แนะนำlist numpy
askewchan

ฉันไม่คิดว่า numpy เร็วที่สุดstackoverflow.com/questions/15889131/…
Chris_Rands

3
ตกลงตามที่ฉันได้กล่าวไว้ข้างต้น การหลีกเลี่ยงปฏิกิริยาเช่นคุณและ @ hpaulj เป็นสาเหตุที่ฉันพยายาม จำกัด ขอบเขตในบรรทัดแรกและบรรทัดสุดท้ายของคำตอบของฉัน: - /
askewchan

1
alex @: การใช้timeit, "ถ้า-nไม่ได้รับเป็นจำนวนที่เหมาะสมของลูปจะถูกคำนวณโดยพยายามอำนาจต่อเนื่อง 10 จนถึงเวลารวมไม่น้อยกว่า 0.2 วินาที." หากคุณคาดหวังว่ามันจะสร้างความแตกต่างคุณสามารถจัดหา-n 1000เพื่อให้เทียบเท่ากันทั้งหมด
askewchan

94

ใน 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]

และใน 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]

5
PEP 572 - นิพจน์การกำหนด (คาดว่างูหลาม 3.8) total = 0; partial_sums = [total := total + v for v in values]แสดงให้เห็นเป็นทางเลือกที่น่าสนใจ ฉันยังคงคาดหวังว่าaccumulateจะเร็วกว่านี้
Steven Rumbalski

3
@StevenRumbalski Man โดยส่วนตัวแล้วผมคิดว่าเป็น PEP ที่แย่ที่สุด แย่พอแล้ว ...
Ashwini Chaudhary

19

ดูเถิด:

a = [4, 6, 12]
reduce(lambda c, x: c + [c[-1] + x], a, [0])[1:]

จะส่งออก (ตามที่คาดไว้):

[4, 10, 22]

17
ไม่มีประสิทธิภาพ ค่าใช้จ่ายทั้งหมดของการดำเนินการc + [c[-1] + x]ซ้ำแล้วซ้ำอีกจะรวมเป็นกำลังสองรันไทม์ทั้งหมดในความยาวอินพุต
user2357112 รองรับ Monica

การลดเป็นสิ่งที่ดีสำหรับผลรวมสะสมเพียงครั้งเดียว แต่ถ้าคุณทำการเรียกใช้ฟังก์ชัน cumsum เป็นจำนวนมากตัวสร้างจะมีประโยชน์ในการ "ประมวลผลล่วงหน้า" ค่าสะสมของค่าสะสมของคุณและเข้าถึงค่าใน O (1) สำหรับการเรียกแต่ละครั้งที่ตามมา
Scott Skiles

18

ฉันทำเครื่องหมายของคำตอบสองอันดับแรกด้วย 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

สำหรับรายการที่ยาวขึ้น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

ถ้า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

หากคุณใส่การนำเข้าที่อยู่ด้านนอกของทั้งสองฟังก์ชั่นและยังคงกลับมา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

10
คุณคงไม่คาดคิดว่าเครื่องบินจะเร็วกว่ารถไฟในการเดินทางข้ามเมืองโดยเฉพาะอย่างยิ่งการซื้อตั๋วและการตรวจสอบความปลอดภัย ในทำนองเดียวกันคุณจะไม่ใช้ numpy ในการประมวลผลlistห้ารายการโดยเฉพาะอย่างยิ่งหากคุณไม่เต็มใจที่จะรับสินค้าarrayคืน หากรายการที่เป็นปัญหานั้นสั้นมากเวลาทำงานของพวกเขาก็จะไม่สำคัญ - การอ้างอิงและความชัดเจนก็จะมีผลเหนือกว่า แต่การใช้listประเภทข้อมูลตัวเลขที่มีความยาวอย่างมีนัยสำคัญอย่างกว้างขวางจะเป็นเรื่องโง่ สำหรับสิ่งนั้นตัวเลขarray จะเหมาะสมและมักจะเร็วกว่า
askewchan

@askewchan ดีฉันไม่เพียงพบสิ่งนี้สำหรับรายการสั้น ๆ และคำถามของ OP ขอให้รายการเป็นผลลัพธ์แทนที่จะเป็นอาร์เรย์ตัวเลข บางทีคุณสามารถแก้ไขคำตอบของคุณให้ชัดเจนขึ้นเมื่อการใช้งานแต่ละครั้งเหมาะสม :)
Chris_Rands

@askewchan อันที่จริงฉันได้แก้ไขคำตอบด้วยการเปรียบเทียบที่ละเอียดกว่านี้มาก ไม่ว่าในสถานการณ์ใดฉันnumpyจะเร็วขึ้นไหมเว้นแต่ฉันจะมองข้ามบางสิ่งไป?
Chris_Rands

2
โอ้ใช่แน่นอน :) ฉันจะไม่บอกว่าคุณมองข้ามบางสิ่งไป แต่การเปรียบเทียบนั้นยากที่จะแยกออกจากกันโดยไม่พิจารณาอินพุตและเอาต์พุตของคุณ เวลาส่วนใหญ่ในsum2ฟังก์ชันของคุณอาจอยู่ในการแปลงlเป็นอาร์เรย์ ลองกำหนดเวลาa = np.array(l)และnp.cumsum(a)แยกกัน แล้วลองเทียบกับa = np.tile(np.arange(1, 6), 1000) l = [1,2,3,4,5]*1000ในโปรแกรมที่ดำเนินกระบวนการเชิงตัวเลขอื่น ๆ (เช่นการสร้างหรือการโหลดlในตอนแรก) ข้อมูลการทำงานของคุณอาจอยู่ในอาร์เรย์แล้วและการสร้างจะมีต้นทุนคงที่
askewchan

1
@askewchan ฉันมีความคิดเดียวกันกับคุณดังนั้นฉันจึงใช้เวลา a = np.array (l) สำหรับ sum2 ที่ไม่มีการแปลงเป็นรายการและด้วยอาร์เรย์ numpy เป็นอินพุต sum2 จะเร็วขึ้น 5 เท่าขอบคุณ sum1 ในคอมพิวเตอร์ของฉันในกรณีที่รายการ / อาร์เรย์แบบยาว
Mantxu

9

ลองสิ่งนี้: ฟังก์ชั่นสะสมพร้อมกับตัวดำเนินการเพิ่มจะดำเนินการเพิ่มที่กำลังทำงานอยู่

import itertools  
import operator  
result = itertools.accumulate([1,2,3,4,5], operator.add)  
list(result)

5
คุณไม่จำเป็นต้องผ่านoperator.addเนื่องจากการดำเนินการเริ่มต้นคือการเพิ่มอยู่ดี
Eugene Yarmash

8

นิพจน์การมอบหมายจาก 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]

5

คุณสามารถคำนวณรายการผลรวมสะสมในเวลาเชิงเส้นด้วยการ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]

ไลบรารีมาตรฐานitertools.accumulateอาจเป็นทางเลือกที่เร็วกว่า (เนื่องจากใช้งานใน C):

from itertools import accumulate
time_interval = [4, 6, 12]
print(list(accumulate(time_interval)))  # [4, 10, 22]


2

ใน Python3 หากต้องการค้นหาผลรวมสะสมของรายการที่iองค์ประกอบ th เป็นผลรวมขององค์ประกอบ i + 1 แรกจากรายการเดิมคุณสามารถทำได้:

a = [4 , 6 , 12]
b = []
for i in range(0,len(a)):
    b.append(sum(a[:i+1]))
print(b)

หรือคุณอาจใช้ความเข้าใจในรายการ:

b = [sum(a[:x+1]) for x in range(0,len(a))]

เอาต์พุต

[4,10,22]

สิ่งนี้ดูเหมือนถูกต้อง แต่สามารถวางลิงก์ไปยังเอกสารโดยที่ฉันไม่สามารถโหวตได้
S Meaden

2

หากคุณต้องการวิธี pythonic โดยไม่ต้องใช้ numpy ใน 2.7 นี่เป็นวิธีของฉันในการทำ

l = [1,2,3,4]
_d={-1:0}
cumsum=[_d.setdefault(idx, _d[idx-1]+item) for idx,item in enumerate(l)]

ตอนนี้เรามาลองและทดสอบกับการใช้งานอื่น ๆ ทั้งหมด

import timeit, sys
L=list(range(10000))
if sys.version_info >= (3, 0):
    reduce = functools.reduce
    xrange = range


def sum1(l):
    cumsum=[]
    total = 0
    for v in l:
        total += v
        cumsum.append(total)
    return cumsum


def sum2(l):
    import numpy as np
    return list(np.cumsum(l))

def sum3(l):
    return [sum(l[:i+1]) for i in xrange(len(l))]

def sum4(l):
    return reduce(lambda c, x: c + [c[-1] + x], l, [0])[1:]

def this_implementation(l):
    _d={-1:0}
    return [_d.setdefault(idx, _d[idx-1]+item) for idx,item in enumerate(l)]


# sanity check
sum1(L)==sum2(L)==sum3(L)==sum4(L)==this_implementation(L)
>>> True    

# PERFORMANCE TEST
timeit.timeit('sum1(L)','from __main__ import sum1,sum2,sum3,sum4,this_implementation,L', number=100)/100.
>>> 0.001018061637878418

timeit.timeit('sum2(L)','from __main__ import sum1,sum2,sum3,sum4,this_implementation,L', number=100)/100.
>>> 0.000829620361328125

timeit.timeit('sum3(L)','from __main__ import sum1,sum2,sum3,sum4,this_implementation,L', number=100)/100.
>>> 0.4606760001182556 

timeit.timeit('sum4(L)','from __main__ import sum1,sum2,sum3,sum4,this_implementation,L', number=100)/100.
>>> 0.18932826995849608

timeit.timeit('this_implementation(L)','from __main__ import sum1,sum2,sum3,sum4,this_implementation,L', number=100)/100.
>>> 0.002348129749298096

2

อาจมีคำตอบมากมายสำหรับสิ่งนี้ขึ้นอยู่กับความยาวของรายการและประสิทธิภาพ วิธีง่ายๆอย่างหนึ่งที่ฉันคิดได้โดยไม่ต้องคำนึงถึงประสิทธิภาพคือ:

a = [1, 2, 3, 4]
a = [sum(a[0:x:1]) for x in range(len(a)+1)][1:]
print(a)

[1, 3, 6, 10]

นี่คือการใช้ความเข้าใจในรายการและสิ่งนี้อาจทำงานได้ดีพอสมควรเพราะที่นี่ฉันเพิ่ม subarray หลาย ๆ ครั้งคุณอาจจะโพล่งออกมาในเรื่องนี้และทำให้มันง่ายขึ้น!

ไชโยกับความพยายามของคุณ!


1

ขั้นแรกคุณต้องการรายการลำดับต่อมา:

subseqs = (seq[:i] for i in range(1, len(seq)+1))

จากนั้นคุณก็โทรsumตามแต่ละครั้ง:

sums = [sum(subseq) for subseq in subseqs]

(นี่ไม่ใช่วิธีที่มีประสิทธิภาพมากที่สุดเพราะคุณกำลังเพิ่มคำนำหน้าทั้งหมดซ้ำ ๆ กัน แต่นั่นอาจไม่สำคัญสำหรับกรณีการใช้งานส่วนใหญ่และจะง่ายกว่าที่จะเข้าใจหากคุณไม่ต้องนึกถึง ผลรวมที่ทำงานอยู่)

หากคุณใช้ Python 3.2 หรือใหม่กว่าคุณสามารถใช้itertools.accumulateเพื่อทำสิ่งนี้ให้คุณได้:

sums = itertools.accumulate(seq)

และหากคุณใช้ 3.1 หรือก่อนหน้านี้คุณสามารถคัดลอกแหล่งที่มา "เทียบเท่ากับ" ได้โดยตรงจากเอกสาร (ยกเว้นการเปลี่ยนnext(it)เป็นit.next()2.5 และก่อนหน้า)


9
สิ่งนี้ทำงานในเวลากำลังสอง (อาจจะไม่สำคัญสำหรับ OP แต่ควรค่าแก่การกล่าวถึง)
Chris Taylor

อันดับแรกเมื่อ N = 3 ใครสนใจเรื่องเวลากำลังสอง? และฉันไม่คิดว่ามันซับซ้อนเกินไป เป็นสองขั้นตอนที่ง่ายมากแต่ละขั้นตอนจะแปลงตัววนซ้ำหนึ่งตัวเป็นอีกตัวแปลคำอธิบายภาษาอังกฤษโดยตรง (ความจริงที่ว่าเขาใช้วิธีที่ไม่ธรรมดาในการกำหนดซีรีส์โดยที่ไม่นับคำนำหน้าความยาว 0 ทำให้ซับซ้อนขึ้นเล็กน้อย… แต่นั่นเป็นปัญหาโดยธรรมชาติและฉันคิดว่ามันจะดีกว่าที่จะใส่ไว้ในrangeกว่าจะแฮ็คโดยทำ[1:]ในตอนท้ายหรือเพิกเฉย)
abarnert

1
สันนิษฐานว่าปัญหาที่แท้จริงของ OP ไม่ใช่เพื่อรับผลรวมบางส่วน[4,6,12]เนื่องจากเขาเขียนไว้ในคำถามเขารู้แล้วว่านั่นคืออะไร!
Chris Taylor

@ChrisTaylor: เขาบอกอย่างชัดเจนว่าเขารู้วิธีเขียนสิ่งนี้แล้ว แต่ต้องการ "วิธีที่ง่ายกว่าในการเขียน"
ยกเลิก


-1
In [42]: a = [4, 6, 12]

In [43]: [sum(a[:i+1]) for i in xrange(len(a))]
Out[43]: [4, 10, 22]

นี่คือslighltyเร็วกว่าวิธีการกำเนิดไฟฟ้าข้างต้นโดย @Ashwini สำหรับรายการขนาดเล็ก

In [48]: %timeit list(accumu([4,6,12]))
  100000 loops, best of 3: 2.63 us per loop

In [49]: %timeit [sum(a[:i+1]) for i in xrange(len(a))]
  100000 loops, best of 3: 2.46 us per loop

สำหรับรายการขนาดใหญ่เครื่องกำเนิดไฟฟ้าเป็นวิธีที่จะไปได้อย่างแน่นอน . .

In [50]: a = range(1000)

In [51]: %timeit [sum(a[:i+1]) for i in xrange(len(a))]
  100 loops, best of 3: 6.04 ms per loop

In [52]: %timeit list(accumu(a))
  10000 loops, best of 3: 162 us per loop

1
คุณกำหนดเวลาเพียง 3 รายการลอง 10 ^ 4 รายการ
Ashwini Chaudhary

1
จริงสำหรับรายการขนาดใหญ่เครื่องกำเนิดไฟฟ้านั้นเร็วกว่ามาก!
สัตว์เลื้อยคลาน

-1

ค่อนข้างแฮ็ค แต่ดูเหมือนจะใช้งานได้:

def cumulative_sum(l):
  y = [0]
  def inc(n):
    y[0] += n
    return y[0]
  return [inc(x) for x in l]

ฉันคิดว่าฟังก์ชันภายในจะสามารถแก้ไขyประกาศในขอบเขตคำศัพท์ภายนอกได้ แต่ไม่ได้ผลดังนั้นเราจึงเล่นแฮ็คที่น่ารังเกียจด้วยการปรับเปลี่ยนโครงสร้างแทน การใช้เครื่องกำเนิดไฟฟ้าอาจจะสวยงามกว่า


-1

โดยไม่ต้องใช้ Numpy คุณสามารถวนซ้ำได้โดยตรงบนอาร์เรย์และสะสมผลรวมไปพร้อมกัน ตัวอย่างเช่น:

a=range(10)
i=1
while((i>0) & (i<10)):
    a[i]=a[i-1]+a[i]
    i=i+1
print a

ผลลัพธ์ใน:

[0, 1, 3, 6, 10, 15, 21, 28, 36, 45]

-1

oneliner หลามบริสุทธิ์สำหรับผลรวมสะสม:

cumsum = lambda X: X[:1] + cumsum([X[0]+X[1]] + X[2:]) if X[1:] else X

นี้เป็นรุ่นที่เวียนเกิดแรงบันดาลใจจากผลรวมสะสม recursive คำอธิบายบางส่วน:

  1. คำแรกX[:1]คือรายการที่มีองค์ประกอบก่อนหน้าและเกือบจะเหมือนกับ[X[0]](ซึ่งจะบ่นว่ารายการว่างเปล่า)
  2. การเรียกซ้ำcumsumในคำที่สองจะประมวลผลองค์ประกอบปัจจุบัน[1]และรายการที่เหลือซึ่งความยาวจะลดลงทีละรายการ
  3. if X[1:]if len(X)>1สั้นสำหรับ

ทดสอบ:

cumsum([4,6,12])
#[4, 10, 22]

cumsum([])
#[]

และจำลองสำหรับผลิตภัณฑ์สะสม:

cumprod = lambda X: X[:1] + cumprod([X[0]*X[1]] + X[2:]) if X[1:] else X

ทดสอบ:

cumprod([4,6,12])
#[4, 24, 288]


-1

นี่เป็นอีกวิธีที่สนุก สิ่งนี้ใช้ประโยชน์จากคำสั่งlocals()ของความเข้าใจนั่นคือตัวแปรท้องถิ่นที่สร้างขึ้นภายในขอบเขตความเข้าใจรายการ:

>>> [locals().setdefault(i, (elem + locals().get(i-1, 0))) for i, elem 
     in enumerate(time_interval)]
[4, 10, 22]

นี่คือlocals()ลักษณะของการวนซ้ำแต่ละครั้ง:

>>> [[locals().setdefault(i, (elem + locals().get(i-1, 0))), locals().copy()][1] 
     for i, elem in enumerate(time_interval)]
[{'.0': <enumerate at 0x21f21f7fc80>, 'i': 0, 'elem': 4, 0: 4},
 {'.0': <enumerate at 0x21f21f7fc80>, 'i': 1, 'elem': 6, 0: 4, 1: 10},
 {'.0': <enumerate at 0x21f21f7fc80>, 'i': 2, 'elem': 12, 0: 4, 1: 10, 2: 22}]

ประสิทธิภาพไม่น่ากลัวสำหรับรายการเล็ก ๆ :

>>> %timeit list(accumulate([4, 6, 12]))
387 ns ± 7.53 ns per loop (mean ± std. dev. of 7 runs, 1000000 loops each)

>>> %timeit np.cumsum([4, 6, 12])
5.31 µs ± 67.8 ns per loop (mean ± std. dev. of 7 runs, 100000 loops each)

>>> %timeit [locals().setdefault(i, (e + locals().get(i-1,0))) for i,e in enumerate(time_interval)]
1.57 µs ± 12 ns per loop (mean ± std. dev. of 7 runs, 1000000 loops each)

และเห็นได้ชัดว่าแบนสำหรับรายการขนาดใหญ่

>>> l = list(range(1_000_000))
>>> %timeit list(accumulate(l))
95.1 ms ± 5.22 ms per loop (mean ± std. dev. of 7 runs, 10 loops each)

>>> %timeit np.cumsum(l)
79.3 ms ± 1.07 ms per loop (mean ± std. dev. of 7 runs, 10 loops each)

>>> %timeit np.cumsum(l).tolist()
120 ms ± 1.23 ms per loop (mean ± std. dev. of 7 runs, 10 loops each)

>>> %timeit [locals().setdefault(i, (e + locals().get(i-1, 0))) for i, e in enumerate(l)]
660 ms ± 5.14 ms per loop (mean ± std. dev. of 7 runs, 1 loop each)

แม้ว่าวิธีนี้จะดูน่าเกลียดและใช้ไม่ได้จริง แต่ก็เป็นเรื่องสนุก


-2
lst = [4,6,12]

[sum(lst[:i+1]) for i in xrange(len(lst))]

หากคุณกำลังมองหาโซลูชันที่มีประสิทธิภาพมากขึ้น (รายการที่ใหญ่กว่า?) เครื่องกำเนิดไฟฟ้าอาจเป็นการโทรที่ดี (หรือใช้เฉพาะในnumpyกรณีที่คุณสนใจเรื่อง perf)

def gen(lst):
    acu = 0
    for num in lst:
        yield num + acu
        acu += num

print list(gen([4, 6, 12]))

-3

นี่จะเป็นสไตล์ Haskell:

def wrand(vtlg):

    def helpf(lalt,lneu): 

        if not lalt==[]:
            return helpf(lalt[1::],[lalt[0]+lneu[0]]+lneu)
        else:
            lneu.reverse()
            return lneu[1:]        

    return helpf(vtlg,[0])
โดยการใช้ไซต์ของเรา หมายความว่าคุณได้อ่านและทำความเข้าใจนโยบายคุกกี้และนโยบายความเป็นส่วนตัวของเราแล้ว
Licensed under cc by-sa 3.0 with attribution required.