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

前端 未结 21 1606
挽巷
挽巷 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:41

    Here's another fun solution. This takes advantage of the locals() dict of a comprehension, i.e. local variables generated inside the list comprehension scope:

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

    Here's what the locals() looks for each iteration:

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

    Performance is not terrible for small lists:

    >>> %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)
    

    And obviously falls flat for larger lists.

    >>> 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)
    

    Even though the method is ugly and not practical, it sure is fun.

提交回复
热议问题