Python中具有默认值的多列表迭代
Posted
技术标签:
【中文标题】Python中具有默认值的多列表迭代【英文标题】:Multi-list iteration with default value in Python 【发布时间】:2017-06-06 19:01:43 【问题描述】:我正在用 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)]
然后我可以过滤掉不必要的实例,但首先生成它们听起来效率低下。有没有什么优雅的方式来构建这个迭代?
【问题讨论】:
【参考方案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】:我提出另一种方法。使用openTURNS。这个python库开发得很好,有一些类用于定义实验设计,据说在空间填充方面具有良好的特性。
请参阅此处的示例 LowDiscrepancySequence。使用此设计,您将能够进行统计分析、创建模型等。我与他们无关,但他们在该领域众所周知。
但是,如果您喜欢,您可以坚持使用您的方法。为了让它更 Pythonic,我会直接构建一个生成器表达式或列表推导:
((I, j, k) for i, j, k in product(...))
【讨论】:
【参考方案3】:请注意,最终列表中每个元组的第 2 和第 3 个实例仅是初始数组的第 2 行和第 3 行的乘积
a, *b = params
# a = [1, 2, 3]
# b = [[4, 5], [7, 8]]
用b中的所有元素制作产品
import itertools
b = [x for x in itertools.product(*b)]
# b = [(4, 7), (4, 8), (5, 7), (5, 8)]
现在用 b 的所有值做 a 的乘积
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)]
整体缩短:
import itertools
params = [[1,2,3],
[4,5],
[7,8]]
a, *b = params
f = itertools.product
c = [(a, b ,c) for a, (b, c) in f(a, f(*b))]
【讨论】:
不是还是先创建所有实例然后过滤掉吗? 我看了你写的最后一个框,认为那是你想要的输出,哦好吧哈哈。以上是关于Python中具有默认值的多列表迭代的主要内容,如果未能解决你的问题,请参考以下文章