Python中使用默认值的多列表迭代

时间:2017-06-06 19:01:44

标签: python iterator itertools

我正在运行python模拟实验,需要创建一个输入案例列表。

每个案例都是从参数列表中获取的实例,例如:

heights = [100,110,120]
alphas = [0.1,0.01,0.001]
C = [0.1,0.2,0.5,0.9]
B = [1,2]

,列表清单是:

params = [heights,alphas,C,B]

原始数量较大(约30x100),因此直接处理每个列表效率不高。

最后,每个输入案例都是每个类别中一个参数的元组/名称元组/字典,例如:

instance = {'height':100, 'alpha':0.1,'C:0.1, 'B':1}

我想迭代参数空间以创建实例列表 - 但这里是捕获

不是制作所有这些的笛卡尔积,而是每个参数我想迭代所有选项,而其余类别则设置为默认值(第一个)。例如:

params = [[1,2,3],[4,5][7,8]]

预期的实例集(没有重复)是:

  

[(1,4,7-),(2,4,7),(3,4,7),(1,5,7)(1,4,8)]

其中 1 是第一个索引的默认值, 4 是第二个索引的默认值, 7 是第三个索引的默认值。

使用itertools

制作笛卡尔积很容易
from itertools import product
params = [[1,2,3],[4,5],[7,8]]
list(product(*params))
  

[(1,4,7),(1,4,8),(1,5,7),(1,5,8),(2,4,7),(2,4,8) ),(2,5,7),(2,5,8),(3,4,7),(3,4,8),(3,5,7),(3,5,8)]

然后我可以过滤掉不必要的实例,但是在第一时间生成它们听起来很不合适。有没有优雅的方法来构建这个迭代?

3 个答案:

答案 0 :(得分:1)

我提出另一种方法。使用openTURNS。这个python库很发达,并且有一些用于定义实验设计的类,据说在空间填充方面具有良好的性能。

请在此处查看示例LowDiscrepancySequence。使用这种设计,您将能够进行统计分析,创建模型等。我与它们无关,但它们在该领域是众所周知的。

然而,如果你préfère你可以坚持你的方法。为了使它更加pythonic我将直接为生成器表达式或列表理解构建:

  

((I,j,k)i,j,k in product(...))

答案 1 :(得分:1)

params = [[1, 2, 3], [4, 5], [7, 8]]
default = [par[0] for par in params]
instances = set()

for ii, pp in enumerate(params):
    for value in pp:
        new_instance = default[:ii] + [value] + default[ii + 1:]
        instances.add(tuple(new_instance))

答案 2 :(得分:0)

请注意,最终列表中每个元组的第2个和第3个实例是仅来自初始数组的第2行和第3行的产品

nuget.exe restore

使用b

中的所有元素制作产品
a, *b = params
# a = [1, 2, 3]
# b = [[4, 5], [7, 8]]

现在做一个具有b

的所有值的a的乘积
import itertools

b = [x for x in itertools.product(*b)]
# b = [(4, 7), (4, 8), (5, 7), (5, 8)]

整体缩短:

c = [(a, b, c) for a, (b, c) in itertools.product(a, b)]

# c = [(1, 4, 7), (1, 4, 8), (1, 5, 7), (1, 5, 8), (2, 4, 7), (2, 4, 8), (2, 5, 7), (2, 5, 8), (3, 4, 7), (3, 4, 8), (3, 5, 7), (3, 5, 8)]