2011-01-25 26 views
5

Duplicar posible:
List comprehension for running totalPython lista por comprensión

Estoy intentando escribir una declaración lista por comprensión concisa para crear una función de distribución: Por ejemplo:

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

Un procedimiento estándar se vería así (quiero escribir una lista de comprensión para e función f()):

def f(probabilities) : 

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

Editar: Encontré una función numpy.cumsum(). Verifico si usa listas de comprensión.

+0

¿Cuál es la pregunta? – Elalfer

+0

@Elalfer - Parece que quiere escribir una lista de comprensión cuyo comportamiento es idéntico al de su función 'f()'. –

+0

Eso es correcto. Mi mal, debería haber sido más explícito. – GeneralBecos

Respuesta

8

Esa operación es tan común que muchos idiomas (principalmente los funcionales, pero no solo) proporcionan abstracciones para ello, generalmente con el nombre scanl (es como un reduce con resultados intermedios). Digamos que es ireduce ("iterativo reducir"):

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

Y ahora utilizarlo:

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

Esto es algo bueno tener en la caja de herramientas de uno; pero seguramente podemos pensar en un nombre más Pythonic en lugar de copiar lo que los otros idiomas llaman? FWIW, C++ llama a esto 'std :: partial_sum', y usa la suma como operación por defecto. –

+0

@Karl. Algunas personas lo llaman ireduce, me gusta. "partial_sum" es un buen nombre cuando se agrega pero con otras operaciones parece algo engañoso. – tokland

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

Pero no hagas eso porque es O (n^2). Las comprensiones de la lista Python no fueron diseñadas para esto. Usa el código de procedimiento que ya escribiste.

+0

Ahora esa es una lista de comprensión impresionante. – user225312

1

No es muy bonita, y no está usando listas por comprensión, pero se puede hacer esto con el reducir falta de apoyo a la lambda de varias líneas

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

de Python hace que este tipo de feo: (función, cuando el valor acumulado es una tupla que sostiene la suma actual y la lista de resultados). Usar una función separada sería mejor:

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] 
Cuestiones relacionadas