2012-05-15 119 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]