Ale*_*len 3 python 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))
Run Code Online (Sandbox Code Playgroud)
......这给了我3072个组合.不幸的是,某些组合在逻辑上毫无意义.E. g.如果a2大于a1,则测试结果是无用的,当b1等于0时,b2的值完全无关 - 所以测试这样的组合是没有意义的.
是否有可能限制或过滤笛卡尔积,只需手动执行并嵌套for循环?因为我的真实用例有超过4个参数,这就是为什么我喜欢itertools中笛卡尔积函数的便利性.
任何想法或替代品?任何帮助表示感谢,谢谢.
您可以使用列表理解或itertools.ifilter:
filtered_params = itertools.ifilter
(lambda (a1, a2, b1, b2): a1 <= a2 and (b1 != 0 or b2 == 5), params)
Run Code Online (Sandbox Code Playgroud)
请注意,这两个版本都会在引擎盖下循环和过滤掉.如果你想避免这种情况,你需要构建一个改进的算法来创建没有不受欢迎的元组.
如果您有很多参数,那么使用像python-constraint这样的模块的基于约束的方法可能更容易使用 - 让它完成找出哪些组合有效的艰苦工作。
这看起来像
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)
Run Code Online (Sandbox Code Playgroud)