python字典,指定随机值,其总和为某个值

python字典,指定随机值,其总和为某个值,python,dictionary,random,Python,Dictionary,Random,我正在制作一个python程序,其中随机值被生成n次,用作模型模拟的参数值 我有一个定义每个参数边界的字典,例如: parameters = {'A': random.uniform(1,10), 'B': random.uniform(20,40)} 我想添加一些参数,其总和必须为1,类似于: params = {'C1': random.uniform(0.0,1.0), 'C2': 1 - params['C1']} params = {'A': random.uniform(1,10

我正在制作一个python程序,其中随机值被生成n次,用作模型模拟的参数值

我有一个定义每个参数边界的字典,例如:

parameters = {'A': random.uniform(1,10), 'B': random.uniform(20,40)}
我想添加一些参数,其总和必须为1,类似于:

params = {'C1': random.uniform(0.0,1.0), 'C2': 1 - params['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]
后者显然不能产生
键错误:“C1”

我也试过这样的方法:

params = {'C1': random.uniform(0.0,1.0), 'C2': 1 - params['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

TypeError:-:“float”和“NoneType”的操作数类型不受支持。


有什么建议吗?

您的代码的问题是因为
dict
在Python中没有排序。当您这样做时:

for key in params['C']
您将在
C1
之前获得
C2
键。实际上,您甚至不需要迭代
dict
,只需在dict中设置值,如:

def class_fractions():
    params['C']['C1'] = random.uniform(0.0,1.0)
    params['C']['C2'] = 1.0 - params['C']['C1']
Yo甚至不需要单独的功能,因为它只更新相同的dict,只需按照以下方式操作:

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

代码的问题是因为
dict
在Python中没有排序。当您这样做时:

for key in params['C']
您将在
C1
之前获得
C2
键。实际上,您甚至不需要迭代
dict
,只需在dict中设置值,如:

def class_fractions():
    params['C']['C1'] = random.uniform(0.0,1.0)
    params['C']['C2'] = 1.0 - params['C']['C1']
Yo甚至不需要单独的功能,因为它只更新相同的dict,只需按照以下方式操作:

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

从您对
for
循环的使用来看,您可能真的拥有比两个参数多得多的参数。在这种情况下,您可以生成一个由随机数填充的值列表,然后将其缩放为一。然后遍历字典键和列表项的压缩视图,并将这些项分配给字典

或者,直接在字典上操作:

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()}

从您对
for
循环的使用来看,您可能真的拥有比两个参数多得多的参数。在这种情况下,您可以生成一个由随机数填充的值列表,然后将其缩放为一。然后遍历字典键和列表项的压缩视图,并将这些项分配给字典

或者,直接在字典上操作:

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()}

如果您确实想使用类_分数,并立即初始化参数,则需要使用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)])}

如果您确实想使用类_分数,并立即初始化参数,则需要使用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)])}

您的for循环将不起作用,因为dict不保证顺序。因此C2可以在C1之前执行。
params['C']['C2']
总是
None
。从不赋值。for循环将不起作用,因为dict不保证顺序。因此C2可以在C1之前执行。
params['C']['C2']
总是
None
。从未赋值。