How to find the cumulative sum of numbers in a list?

前端 未结 21 1627
挽巷
挽巷 2020-11-22 02:09
time_interval = [4, 6, 12]

I want to sum up the numbers like [4, 4+6, 4+6+12] in order to get the list t = [4, 10, 22].

相关标签:
21条回答
  • 2020-11-22 02:57

    Assignment expressions from PEP 572 (new in Python 3.8) offer yet another way to solve this:

    time_interval = [4, 6, 12]
    
    total_time = 0
    cum_time = [total_time := total_time + t for t in time_interval]
    
    0 讨论(0)
  • 2020-11-22 02:58

    Somewhat hacky, but seems to work:

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

    I did think that the inner function would be able to modify the y declared in the outer lexical scope, but that didn't work, so we play some nasty hacks with structure modification instead. It is probably more elegant to use a generator.

    0 讨论(0)
  • 2020-11-22 02:58
    lst = [4,6,12]
    
    [sum(lst[:i+1]) for i in xrange(len(lst))]
    

    If you are looking for a more efficient solution (bigger lists?) a generator could be a good call (or just use numpy if you really care about perf).

    def gen(lst):
        acu = 0
        for num in lst:
            yield num + acu
            acu += num
    
    print list(gen([4, 6, 12]))
    
    0 讨论(0)
  • 2020-11-22 03:02

    Try this: accumulate function, along with operator add performs the running addition.

    import itertools  
    import operator  
    result = itertools.accumulate([1,2,3,4,5], operator.add)  
    list(result)
    
    0 讨论(0)
  • 2020-11-22 03:02
    values = [4, 6, 12]
    total  = 0
    sums   = []
    
    for v in values:
      total = total + v
      sums.append(total)
    
    print 'Values: ', values
    print 'Sums:   ', sums
    

    Running this code gives

    Values: [4, 6, 12]
    Sums:   [4, 10, 22]
    
    0 讨论(0)
  • 2020-11-22 03:02

    If You want a pythonic way without numpy working in 2.7 this would be my way of doing it

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

    now let's try it and test it against all other implementations

    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
    
    0 讨论(0)
提交回复
热议问题