List comprehension for running total

前端 未结 13 1340
感动是毒
感动是毒 2020-12-05 02:47

I want to get a running total from a list of numbers.

For demo purposes, I start with a sequential list of numbers using range

a = range         


        
相关标签:
13条回答
  • 2020-12-05 03:32

    This can be implemented in 2 lines in Python.

    Using a default parameter eliminates the need to maintain an aux variable outside, and then we just do a map to the list.

    def accumulate(x, l=[0]): l[0] += x; return l[0];
    map(accumulate, range(20))
    
    0 讨论(0)
  • 2020-12-05 03:32

    I wanted to do the same thing to generate cumulative frequencies that I could use bisect_left over - this is the way I've generated the list;

    [ sum( a[:x] ) for x in range( 1, len(a)+1 ) ]
    
    0 讨论(0)
  • 2020-12-05 03:35

    Another one-liner, in linear time and space.

    def runningSum(a):
        return reduce(lambda l, x: l.append(l[-1]+x) or l if l else [x], a, None)
    

    I'm stressing linear space here, because most of the one-liners I saw in the other proposed answers --- those based on the pattern list + [sum] or using chain iterators --- generate O(n) lists or generators and stress the garbage collector so much that they perform very poorly, in comparison to this.

    0 讨论(0)
  • 2020-12-05 03:35

    This is inefficient as it does it every time from beginning but possible it is:

    a = range(20)
    runtot=[sum(a[:i+1]) for i,item in enumerate(a)]
    for line in zip(a,runtot):
        print line
    
    0 讨论(0)
  • 2020-12-05 03:38

    Here's a linear time solution one liner:

    list(reduce(lambda (c,s), a: (chain(c,[s+a]), s+a), l,(iter([]),0))[0])
    

    Example:

    l = range(10)
    list(reduce(lambda (c,s), a: (chain(c,[s+a]), s+a), l,(iter([]),0))[0])
    >>> [0, 1, 3, 6, 10, 15, 21, 28, 36, 45]
    

    In short, the reduce goes over the list accumulating sum and constructing an list. The final x[0] returns the list, x[1] would be the running total value.

    0 讨论(0)
  • 2020-12-05 03:40

    If you can use numpy, it has a built-in function named cumsum that does this.

    import numpy
    tot = numpy.cumsum(a)  # returns a numpy.ndarray
    tot = list(tot)        # if you prefer a list
    
    0 讨论(0)
提交回复
热议问题