Python - 列表中的笛卡尔积在某些列表中具有随机变量

Python - Cartesian product on lists with random variables in some of the list

我想在一些列表之间做笛卡尔积

某些列表可能包含随机变量,应在产品执行时将其随机化。

下面的方法我试过了

import random


a_list = ['low', 'medium', 'high']
b_list = [0, 1]

dict_list = []
for a in a_list:
    for b in b_list:
        if a == 'low':
            a_random = random.uniform(0, 3)
        elif a == 'medium':
            a_random = random.uniform(3, 6)
        elif a == 'high':
            a_random = random.uniform(6, 100)
        dict_list.append({'a': a_random, 'b': b})

print(dict_list)

输出:

[{'a': 2.5067206438005165, 'b': 0},
{'a': 2.846737783049243, 'b': 1},
{'a': 4.515841550661135, 'b': 0},
{'a': 5.570169974274982, 'b': 1},
{'a': 26.509898440764896, 'b': 0},
{'a': 57.48321086944802, 'b': 1}]

以上示例只是一个玩具示例。

我的实际情况会有更多的列表和更多的随机变量。 例如:

# a_list = [random.uniform(0, 3), random.uniform(3, 6), random.uniform(6, 100)]
a_list = ['low', 'medium', 'high'] 
b_list = [0, 1]
# c_list = [random.uniform(0, 10), random.uniform(10, 100), random.uniform(100, 1000)]
c_list = ['low', 'medium', 'high']
d_list = ['A', 'B', 'C', 'D']

是否有更好的方法可以达到同样的效果?

也许使用 itertools?还是发电机?

谢谢!

创建列表后处理随机数。

def lookup1(val):
    if val == 'low':
        return random.uniform(0,3)
    elif val == 'medium':
        return random.uniform(3,6)
    else:
        return random.uniform(6,100)

want = []
for a,b in itertools.product(a_list, b_list):
    want.append( [lookup1(a), b] )

您可以进一步参数化它。也许创建一个 Distribution class 来保存分布并生成正确的范围。

跟进

以下是将分发点嵌入到 class 中的方法:

class Distribution:
    def __init__( self, limits ):
        self.limits = limits

    def lookup(self, val):
        l = self.limits
        if val == 'low':
            return random.uniform(l[0],l[1])
        elif val == 'medium':
            return random.uniform(l[1],l[2])
        else:
            return random.uniform(l[2],l[3])

distr_a = Distribution( [0, 3, 6, 100] )
distr_b = Distribution( [0, 10, 100, 1000] )

want = []
for a,b in itertools.product(a_list, b_list):
    want.append( [distr_a.lookup(a), b] )

留给 reader 将其扩展到 ['low'、'medium'、'high'] 以外的列表作为练习。即使那样也不难。