Python list comprehension [duplicate]
Possible Duplicate:
List comprehension for running total
I'm trying to write a concise list comprehension statement to create a cdf: For example:
print f([0.2, 0.3,0.1,0.4])
[0.2,0.5,0.6,1.0]
A standard procedure would look like this (I want to write a list comprehension for the function f()):
def f(probabilities) :
sum = 0
returnList = []
for count in probabilities:
sum +=count
returnList = returnList + [sum]
return returnList
Edit: I found a function numpy.cumsum(). I'll check if it uses list comprehensions.
That operation is so common that many languages (mainly functional ones, but not only) provide abstractions for it, usually with the name scanl
(it's like a reduce
with intermediate results). Let's call it ireduce
("iterative reduce"):
def ireduce(f, state, it):
for x in it:
state = f(state, x)
yield state
And now use it:
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]
[sum(probabilities[:i+1]) for i in range(len(probabilities))]
But don't do that because it's O(n^2). Python list comprehensions weren't designed for this. Use the procedural code that you already wrote.
It's not really pretty, and it's not using list comprehensions, but you can do this with the reduce() function, where the accumulated value is a tuple holding the current sum and the result list:
a = [0.2, 0.3, 0.1, 0.4]
reduce((lambda result, val: (result[0] + val, result[1] + [result[0] + val])), a, (0, []))[1]
Python's lack of support for multi-line lambda's makes this kind of ugly. Using a separate function would be better:
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]
精彩评论