2011-01-25 15 views
5

Powiel możliwe:
List comprehension for running totalPython listowego

Próbuję napisać zwięzłe listowych stworzyć CDF: Na przykład:

print f([0.2, 0.3,0.1,0.4]) 
[0.2,0.5,0.6,1.0] 

Standardowa procedura wyglądałaby tak (chcę napisać listę zrozumiałą dla e funkcja f()):

def f(probabilities) : 

    sum = 0 
    returnList = [] 
    for count in probabilities: 
     sum +=count 
     returnList = returnList + [sum] 
    return returnList 

Edytuj: Znalazłem funkcję numpy.cumsum(). Sprawdzę, czy korzysta ze spisanych słów.

+0

Na czym polega pytanie? – Elalfer

+0

@Elalfer - Wygląda na to, że chce napisać listę, której zachowanie jest identyczne z jego funkcją 'f()'. –

+0

To prawda. Mój zły, powinienem być bardziej wyraźny. – GeneralBecos

Odpowiedz

8

Ta operacja jest tak powszechna, że ​​wiele języków (głównie funkcjonalnych, ale nie tylko) dostarcza do niej abstrakcje, zwykle o nazwie scanl (to jest jak reduce z wynikami pośrednimi). Nazwijmy go ireduce („iteracyjny zmniejszyć”):

def ireduce(f, state, it): 
    for x in it: 
     state = f(state, x) 
     yield state 

I teraz używać go:

import operator 

def f(probabilities): 
    return ireduce(operator.add, 0, probabilities) 

print(list(f([0.2, 0.3,0.1,0.4]))) 
# [0.2, 0.5, 0.6, 1.0] 
+0

Dobrze jest mieć w swoim zestawie narzędzi; ale na pewno możemy wymyślić bardziej Pythonową nazwę zamiast kopiować to, co nazywają ją inne języki? FWIW, C++ nazywa tę 'std :: partial_sum' i domyślnie używa jako operacji dodawania. –

+0

@Karl. Niektórzy nazywają to ireduce, lubię to. "partial_sum" to dobra nazwa podczas dodawania, ale w przypadku innych operacji wydaje się nieco myląca. – tokland

8
[sum(probabilities[:i+1]) for i in range(len(probabilities))] 

Ale nie rób tego, ponieważ jest to O (n^2). Zrozumienia listy w języku Python nie zostały zaprojektowane do tego celu. Użyj kodu proceduralnego, który już napisałeś.

+0

Teraz jest to jedna niesamowita lista ze zrozumieniem. – user225312

1

To naprawdę nie jest ładna, i nie używa wyrażeń listowych, ale można to zrobić za pomocą zmniejszenia() funkcja, gdzie skumulowana wartość jest krotką posiadających aktualną sumę i listę wyników: brak

a = [0.2, 0.3, 0.1, 0.4] 
reduce((lambda result, val: (result[0] + val, result[1] + [result[0] + val])), a, (0, []))[1] 

Pythona z obsługą multi-line lambda czyni ten rodzaj brzydki. Używanie oddzielnej funkcji byłoby lepsze:

a = [0.2, 0.3, 0.1, 0.4] 
    def accumulate(result, val): 
     return (result[0] + val, result[1] + [result[0] + val]) 

    reduce(accumulate, a, (0, []))[1]