2013-11-27 32 views
1

我需要找到一組概率的子列表,使得子列表的負二進制對數之和爲1(或剛剛過去1.0)。只需找到第一個這樣的子列表就可以了。部分和時產生收益

要做到這一點,我想我可以使用takewhile和生成器表達式,但我似乎無法讓事情工作。

到目前爲止,我有:

from itertools import takewhile 
from numpy.random import dirichlet 
from math import log 

def partial_sums(iterable): 
    total = 0 
    for i in iterable: 
     total += -1*log(i,2) 
     yield total 

probs = dirichlet([1]*1000).tolist() 
probs = 10*probs 
ps = partial_sums(probabilities) 
s = takewhile(lambda x: x<1, sum(x for x in partial_sums(probs))) 

這只是給我一個空列表但是。

編輯:如果我使用Python,我可以用itertools.accumulate:

s = takewhile(lambda x: x<1, itertools.accumulate(math.log(x,2) for x in probs)) 

我正在尋找一個Python 2.7當量。

編輯:我想這:

def partial_sums(iterable): 
    total = 0 
    for i in iterable: 
     total += -1*log(i,2) 
     if total >= 1.0: 
      yield i 

會的工作,但可惜事實並非如此。

+0

您正在運行'sum()',它返回*一個值*。這不是'takewhile()'循環的迭代,而是會導致錯誤。如果sum()不是內置的,它來自哪裏? –

+0

另外,你的意思是使用'partial_sums(probs)'而不是'partial_sums(概率)'? –

+0

您的**第一個**值已超過1; 'next(ps)'返回'12.091043076201494'。 –

回答

0

我找到了解決辦法:

from itertools import takewhile 
from numpy.random import dirichlet 
from math import log 

def partial_sums(iterable): 
    total = 0 
    for i in iterable: 
     total += i 
     yield total 

probs = dirichlet([1]*1000).tolist() 
probs = 10*probs 
s = takewhile(lambda x: x<1, partial_sums(-1*log(x,2) for x in probs)) 

編輯:正如馬亭皮特斯指出,對於itertools.accumulate文檔包含以下功能,爲Python 2正常工作:

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 

這應該在上面的解決方案中用來代替partial_sums()。