2012-05-15 60 views
0
from random import uniform 

prob = [0.25,0.30,0.45] 

def onetrial(prob): 
    u=uniform(0,1) 
    if 0 < u <= prob[0]: 
     return 11 
    if prob[0] < u <= prob[0]+prob[1]: 
     return 23 
    if prob[0]+prob[1] < u <= prob[0]+prob[1]+prob[2]: 
     return 39 

print onetrial(prob) 

我不知道如何使用一些for-loop技术来减少def中的重复部分。谢谢。For循环,在Python中重复计算

+1

看起来像一些类型的轮盘选择..我不认为代码是不清楚,将'prob'变得更大或变化?我只是很好奇这个动机 - 谢谢 – Levon

+1

你不需要测试'<'部分(由前面的if处理)。 –

+2

如果您假设概率总和为1.0,则可以完全跳过最后一个“if”。如果四舍五入会导致错过最后一个条件并结束该函数,这样做也会更安全。 –

回答

0

假设你叫onetrial频繁,计算CDF先让它快一点:

from random import uniform 

vals = [11, 23, 39] 
prob = [0.25, 0.30, 0.45] 
cdf = [sum(prob[0:i+1]) for i in xrange(3)] 

def onetrial(vals, cdf): 
    u = uniform(0, 1) 
    for i in range(3): 
     if u <= cdf[i]: 
      return vals[i] 

您可以使用bisect使其更快。

+1

为什么你在函数中有概率? – deinonychusaur

+1

这行'def onetrial(prob):'应该是'def onetrial(cdf,vals):'我认为 – jgritty

+0

@jgritty,我测试了你的。我认为或者有效。 –

1

以下是相当于当前的代码,它使用一个for循环:

from random import uniform 

prob = [0.25, 0.30, 0.45] 

def onetrial(prob): 
    u = uniform(0, 1) 
    return_values = [11, 23, 39] 
    total_prob = 0 
    for i in range(3): 
     total_prob += prob[i] 
     if u <= total_prob: 
      return return_values[i] 

我在你返回值与概率之间的关系有点不清楚,好像对你的代码prob总是有3个元素,所以我也做了这个假设。

1

我喜欢FJ的答案,但我会用一个元组列表,假设你可以很容易地做到这一点:

from random import uniform 

prob = [(0.25, 11), (0.30, 23), (0.45, 39)] 

def onetrial(prob): 
    u = uniform(0, 1) 
    total_prob = 0 
    for i in range(3): 
     total_prob += prob[i][0] 
     if u <= total_prob: 
      return prob[i][1]