Python - 列表上的笛卡尔积,其中一些列表中有随机变量

发布于 2025-01-09 11:30:34 字数 1300 浏览 0 评论 0原文

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

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

我尝试过以下方法。

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']

是否有更好的方法来达到相同的结果?

也许使用itertool?或发电机?

谢谢!

I want to do Cartesian product between some lists.

Some of the lists might contain random variables that should be randomized when the product perform.

I have tried the following method.

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)

Output:

[{'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}]

The above example is just a toy example.

There will be more lists and more random variables in my actual situation.
e.g.:

# 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']

Is there better ways to achieve the same result?

Maybe using itertools? or generators?

Thanks!

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(1

爱你不解释 2025-01-16 11:30:34

创建列表后处理随机数。

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 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] )

将其扩展为除 ['low','medium','high'] 之外的列表,作为练习留给读者。即使这样也不难。

Handle the randoms after you create the list.

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] )

You could probably parameterize that even more. Maybe create a Distribution class that holds the distribution and generates the right ranges.

Followup

Here's how you might embed the distribution points into a 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] )

It is left as an exercise for the reader to extend this to lists other than ['low','medium','high']. Even that isn't hard.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文