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

前端 未结 21 1485
挽巷
挽巷 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条回答
  • Try this:

    result = []
    acc = 0
    for i in time_interval:
        acc += i
        result.append(acc)
    
    0 讨论(0)
  • 2020-11-22 02:45

    You can calculate the cumulative sum list in linear time with a simple for loop:

    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]
    

    The standard library's itertools.accumulate may be a faster alternative (since it's implemented in C):

    from itertools import accumulate
    time_interval = [4, 6, 12]
    print(list(accumulate(time_interval)))  # [4, 10, 22]
    
    0 讨论(0)
  • 2020-11-22 02:45
    l = [1,-1,3]
    cum_list = l
    
    def sum_list(input_list):
        index = 1
        for i in input_list[1:]:
            cum_list[index] = i + input_list[index-1]
            index = index + 1 
        return cum_list
    
    print(sum_list(l))
    
    0 讨论(0)
  • 2020-11-22 02:48

    In Python 2 you can define your own generator function like this:

    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]
    

    And in Python 3.2+ you can use itertools.accumulate():

    In [1]: lis = [4,6,12]
    
    In [2]: from itertools import accumulate
    
    In [3]: list(accumulate(lis))
    Out[3]: [4, 10, 22]
    
    0 讨论(0)
  • 2020-11-22 02:50

    If you're doing much numerical work with arrays like this, I'd suggest numpy, which comes with a cumulative sum function cumsum:

    import numpy as np
    
    a = [4,6,12]
    
    np.cumsum(a)
    #array([4, 10, 22])
    

    Numpy is often faster than pure python for this kind of thing, see in comparison to @Ashwini's accumu:

    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
    

    But of course if it's the only place you'll use numpy, it might not be worth having a dependence on it.

    0 讨论(0)
  • 2020-11-22 02:53

    I did a bench-mark of the top two answers with Python 3.4 and I found itertools.accumulate is faster than numpy.cumsum under many circumstances, often much faster. However, as you can see from the comments, this may not always be the case, and it's difficult to exhaustively explore all options. (Feel free to add a comment or edit this post if you have further benchmark results of interest.)

    Some timings...

    For short lists accumulate is about 4 times faster:

    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
    

    For longer lists accumulate is about 3 times faster:

    l = [1, 2, 3, 4, 5]*1000
    timeit(lambda: sum1(l), number=100000)
    # 19.174508565105498
    timeit(lambda: sum2(l), number=100000)
    # 61.871223849244416
    

    If the numpy array is not cast to list, accumulate is still about 2 times faster:

    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
    

    If you put the imports outside of the two functions and still return a numpy array, accumulate is still nearly 2 times faster:

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