Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/python/327.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Python笛卡尔积和条件?_Python_Itertools - Fatal编程技术网

Python笛卡尔积和条件?

Python笛卡尔积和条件?,python,itertools,Python,Itertools,在Python中,我使用itertools.product()函数为模拟生成输入参数 我有一个测试函数,需要4个输入参数a1、a2、b1和b2。我使用下面的代码生成参数。例如: params = itertools.product(range(10,41,2), range(10,41,2), range(0, 2), range(5, 31, 5)) …这给了我3072个组合。不幸的是,有些组合在逻辑上毫无意义。例如。如果a2大于a1,测试结果是无用的,而且当b1等于0时,b2的值是完全不相

在Python中,我使用itertools.product()函数为模拟生成输入参数

我有一个测试函数,需要4个输入参数a1、a2、b1和b2。我使用下面的代码生成参数。例如:

params = itertools.product(range(10,41,2), range(10,41,2), range(0, 2), range(5, 31, 5))
…这给了我3072个组合。不幸的是,有些组合在逻辑上毫无意义。例如。如果a2大于a1,测试结果是无用的,而且当b1等于0时,b2的值是完全不相关的——因此测试此类组合是没有意义的

除了手动操作和嵌套循环外,是否有可能限制或过滤笛卡尔积?因为我的实际用例有4个以上的参数,所以我喜欢itertools中笛卡尔积函数的便利性

有什么想法或选择吗?
感谢您的帮助。

您可以将列表理解与对所选参数的任何限制结合使用。我建议在执行此操作之前将参数放入一个集合中,以确保没有不必要的代码。在您上面提到的情况下,我不会出现这种情况,但是人们并不总是使用
range
来生成参数选项

例如,这里创建了一个元组参数列表,其中只有当参数1大于参数2+10时,它才是有效的组合:

acceptableParamCombinations = 
[ (p1,p2) for p1 in set(range(10,41,2)) for p2 in set(range(10,41,2)) if p1 > p2 + 10 ]

一个选项是使
params
成为另一个发电机,该发电机本身由
itertools.product
供电

例如:

params = (prod for prod in itertools.product(...) if prod[2] <= prod[1])
params=(itertools.product(…)中prod的prod,如果prod[2]Python 3
在Python 3中,您可以使用以下方法过滤掉不需要的组合:


请注意,这两个版本都是在后台循环和过滤的。如果你想避免这种情况,你需要构造一个改进的算法,创建元组而不包含不受欢迎的内容。

如果你有很多参数,使用类似模块的基于约束的方法可能更容易使用-让它来做艰苦的工作哪些组合是有效的

这看起来像

from constraint import Problem

prob = Problem()
prob.addVariables(["a1", "a2"], range(10,41,2))
prob.addVariable("b1", [0, 2])
prob.addVariable("b2", range(5, 31, 5))
prob.addConstraint(lambda a1, a2: a2 <= a1, ["a1", "a2"])
prob.addConstraint(lambda b1, b2: b1 != 0 or b2 == 5, ["b1", "b2"])

for params in prob.getSolutionIter():
    run_sim(**params)
来自约束导入问题的

prob=问题()
问题添加变量([“a1”,“a2”],范围(10,41,2))
prob.addVariable(“b1”[0,2])
prob.addVariable(“b2”,范围(5,31,5))

prob.addConstraint(lambda a1,a2:a2在这种情况下,使用numpy的向量运算表达规则是最方便/直观/可读的。例如:

import numpy as np

arr = np.array(list(params), dtype = [('a1',int),('a2',int),('b1',int),('b2',int)])
arr = arr[ arr['a2'] <= arr['a1'] ]
arr = arr[ arr['b1'] != 0 ]
将numpy导入为np
arr=np.array(list(params),dtype=[('a1',int),('a2',int),('b1',int),('b2',int)])

arr=arr[arr['a2']如果您的用例要复杂得多,您可以查看一个数组包,如
numpy
(例如,这并不完全是您想要的,但可能是相关的:)
itertools.product
没有筛选参数,因此您必须自己做-要么编写自己的生成器,类似于
itertools.product
文档中的示例,要么事后对其进行筛选。太棒了,谢谢。我是否理解此解决方案不会首先创建一个巨大的矩阵,而不是减少它…但只添加有意义的值?!@Alen:我相信它使用了分支和绑定-它会查看a1的每个值,然后是a2的每个值,这不会破坏任何约束,等等。
from constraint import Problem

prob = Problem()
prob.addVariables(["a1", "a2"], range(10,41,2))
prob.addVariable("b1", [0, 2])
prob.addVariable("b2", range(5, 31, 5))
prob.addConstraint(lambda a1, a2: a2 <= a1, ["a1", "a2"])
prob.addConstraint(lambda b1, b2: b1 != 0 or b2 == 5, ["b1", "b2"])

for params in prob.getSolutionIter():
    run_sim(**params)
import numpy as np

arr = np.array(list(params), dtype = [('a1',int),('a2',int),('b1',int),('b2',int)])
arr = arr[ arr['a2'] <= arr['a1'] ]
arr = arr[ arr['b1'] != 0 ]