2016-11-15 51 views
1

我正在製作一個python程序,其中隨機值生成n次,用作模型仿真的參數值。python詞典,賦值爲總和值爲一定值的隨機值

我定義每個參數的邊界的字典,例如:

parameters = {'A': random.uniform(1,10), 'B': random.uniform(20,40)} 

我想添加一些參數,其總和必須是1,是這樣的:

params = {'C1': random.uniform(0.0,1.0), 'C2': 1 - params['C1']} 

後者顯然不起作用KeyError: 'C1'

我也試過類似的東西:

params = {'A': random.uniform(1,10), 'B': random.uniform(20,40), 'C': {'C1': None,'C2': None}} 

def class_fractions(): 
    for key in params['C']: 
     if key == 'C1': 
      params['C'][key] = random.uniform(0.0,1.0) 
     if key == 'C2': 
      params['C'][key] = 1.0 - params['C'][key] 

但在調用函數後我得到的類型錯誤

TypeError: unsupported operand type(s) for -: 'float' and 'NoneType'

什麼建議嗎?

+0

您的for循環將不起作用,因爲字典不保證順序。所以C2可以在C1之前執行。 – Marcin

+0

'params ['C'] ['C2']'總是'None'。從未分配過一個值。 – helloV

回答

1

從您使用for循環看起來,您可能確實擁有的參數不止兩個。在這種情況下,您可以生成一個填充了隨機數的值列表,然後然後將其縮小爲一,as described in this other answer。然後迭代字典鍵和列表項目的壓縮視圖,並將項目分配給字典。

或者,直接在字典操作:

params = {k: random.uniform(0, 1) for k in ('C1', 'C2', 'C3')} 
total = sum(params.values()) 
params = {k: (v/total) for k, v in params.items()} 
2

您的代碼問題是因爲dict未在Python中進行排序。當你這樣做:

for key in params['C'] 

你比以前C1越來越C2關鍵。其實你甚至不需要迭代中,如字典的dict只需設置值:

def class_fractions(): 
    params['C']['C1'] = random.uniform(0.0,1.0) 
    params['C']['C2'] = 1.0 - params['C']['C1'] 

喲甚至不需要單獨的功能,因爲它僅更新同一字典,只要你不喜歡它:

params = {'A': random.uniform(1,10), 'B': random.uniform(20,40)} # create partial dict 
c_dict = {'C1': random.uniform(1,10)} # create sub-dict to store random value 
c_dict['C2'] = 1 - c_dict['C1'] # get value that you want 
params['C'] = c_dict  # add entry into parent dict 
1

如果你真的想OT使用class_fraction,並在一次初始化參數,可以那麼就需要使用OrderDict:

import random 
from collections import OrderedDict 

params = {'A': random.uniform(1,10), 'B': random.uniform(20,40), 'C':OrderedDict([('C1', None),('C2', None)])} 


def class_fractions(): 
    for key in params['C']: 
     if key == 'C1': 
      params['C'][key] = random.uniform(0.0,1.0) 
     if key == 'C2': 
      params['C'][key] = 1.0 - params['C']['C1'] 


class_fractions() 
print(params) 

結果:

{'B': 37.3088618142464, 'A': 2.274415152225316, 'C': OrderedDict([('C1', 0.12703200100786471), ('C2', 0.8729679989921353)])}