开发者

Python list comprehension [duplicate]

This question already has answers here: 开发者_运维技巧 Closed 12 years ago.

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]
0

上一篇:

下一篇:

精彩评论

暂无评论...
验证码 换一张
取 消

最新问答

问答排行榜