Pythonic reduce with accumlation and arbitrary lambda function?

后端 未结 1 762
时光说笑
时光说笑 2021-01-18 21:07

What would be the Pythonic way of performing a reduce with accumulation?

For example, take R\'s Reduce(). Given a list and an arbitrary lambda function

相关标签:
1条回答
  • 2021-01-18 21:34

    In Python 3 (introduced in 3.2, ability to pass the function added in 3.3) this is already implemented, in itertools.accumulate. Just use it like this:

    from itertools import accumulate
    list(accumulate([5, 4, 3, 2], lambda a, b: a*b))
    # [5, 20, 60, 120]
    

    If you are using an earlier Python version, or want to implement it yourself, and you really want any arbitrary lambda (that takes two arguments) to work, then you could use the generator which is given in the documentation of the above:

    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)
        try:
            total = next(it)
        except StopIteration:
            return
        yield total
        for element in it:
            total = func(total, element)
            yield total
    

    The usage is exactly the same as above.


    If you are using numpy, then there exists a faster solution, at least for all numpy.ufuncs. These include basically the same functions that the standard library module math provides, and then some. You can find a complete list here.

    Every numpy.ufunc has the accumulate method, so you can just do:

    import numpy as np
    np.multiply.accumulate([5, 4, 3, 2])
    # array([  5,  20,  60, 120])
    
    0 讨论(0)
提交回复
热议问题