2013-11-26 2 views
8

Каков наилучший способ репликации этой простой функции с использованием понимания списка (или другого компактного подхода)?Сопоставление списка с аккумулятором

import numpy as np 

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

Вы используете NumPy случайно? Я знаю, что numpy имеет хорошую функцию для чего-то подобного. – arshajii

+1

Я бы не использовал понимание списка - элементы должны быть независимы друг от друга, и в этом случае они не являются. – Izkata

+1

Почему вы хотите превратить это в понимание списка? Гораздо читабельнее держать это в отдельном цикле. Сделайте это 'array = [0]', 'для i в rand (100): возможно, array.append (i + array [-1])'. –

ответ

6

В Python 3, вы будете использовать itertools.accumulate():

from itertools import accumulate 

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

накапливались дает бегущего результат суммирования значений входного Iterable, начиная с первого значения:

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

Вы можете передать другую операцию в качестве второго аргумента; это должно быть вызываемым, которое берет накопленный результат и следующее значение, возвращая новый накопленный результат. operator module очень помогает в предоставлении стандартных математических операторов для такого рода работ; вы можете использовать его, чтобы произвести ход умножения результат, например:

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

Функциональность достаточно легко портировать на более старых версиях (Python 2, или Python 3.0 или 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 
+0

Это работает, но я искал что-то вроде понимания списка для компактного использования - например, в командной строке ipython. – Pierz

+0

@Pierz: Я использовал 'list()' на 'accumulate()' iterator, чтобы дать вам быстрый список значений. Вы все равно можете использовать его в понимании списка, '[v для v в накоплении (rand (100))]; вы не можете сделать это с помощью * просто * понимания списка, потому что у вас нет доступа к предыдущим элементам, сгенерированным до сих пор. –

+0

Правда, это элегантный подход, но я не был уверен, был ли аккуратный способ накопить накопленную сумму в понимании списка. Согласился, что это, вероятно, не лучшая практика, но при работе в командной строке удобно использовать компактные формы. – Pierz

4

Так как вы «повторно уже с помощью numpy, вы можете использовать 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]) 
1

Хорошо, вы сказали, что вы не хотите numpy, но вот мое решение в любом случае. Мне кажется, что вы просто берете кумулятивную сумму, поэтому используете функцию cumsum().

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

Для случайного примера

result = np.cumsum(np.random.uniform(size=100)) 
Смежные вопросы