List comprehension with an accumulator

2020-08-16 02:49发布

问题:

What is the best way to replicate this simple function using a list comprehension (or another compact approach)?

import numpy as np

sum=0
array=[]
for i in np.random.rand(100):
   sum+=i
   array.append(sum)

回答1:

In Python 3, you'd use itertools.accumulate():

from itertools import accumulate

array = list(accumulate(rand(100)))

Accumulate yields the running result of adding up the values of the input iterable, starting with the first value:

>>> from itertools import accumulate
>>> list(accumulate(range(10)))
[0, 1, 3, 6, 10, 15, 21, 28, 36, 45]

You can pass in a different operation as a second argument; this should be a callable that takes the accumulated result and the next value, returning the new accumulated result. The operator module is very helpful in providing standard mathematical operators for this kind of work; you could use it to produce a running multiplication result for example:

>>> import operator
>>> list(accumulate(range(1, 10), operator.mul))
[1, 2, 6, 24, 120, 720, 5040, 40320, 362880]

The functionality is easy enough to backport to older versions (Python 2, or Python 3.0 or 3.1):

# Python 3.1 or before

import operator

def accumulate(iterable, func=operator.add):
    'Return running totals'
    # accumulate([1,2,3,4,5]) --> 1 3 6 10 15
    # accumulate([1,2,3,4,5], operator.mul) --> 1 2 6 24 120
    it = iter(iterable)
    total = next(it)
    yield total
    for element in it:
        total = func(total, element)
        yield total


回答2:

Since you're already using numpy, you can use cumsum:

>>> from numpy.random import rand
>>> x = rand(10)
>>> x
array([ 0.33006219,  0.75246128,  0.62998073,  0.87749341,  0.96969786,
        0.02256228,  0.08539008,  0.83715312,  0.86611906,  0.97415447])
>>> x.cumsum()
array([ 0.33006219,  1.08252347,  1.7125042 ,  2.58999762,  3.55969548,
        3.58225775,  3.66764783,  4.50480095,  5.37092001,  6.34507448])


回答3:

Ok, you said you did not want numpy but here is my solution anyway. It seems to me that you are simply taking the cumulative sum, thus use the cumsum() function.

import numpy as np
result = np.cumsum(some_array)

For a random example

result = np.cumsum(np.random.uniform(size=100))