您可以使用itertools.product 函数,该函数获取迭代器列表并创建其笛卡尔积的迭代器(请参阅documentation)。
在我的解决方案中,我使用 parameter 字典中的值作为迭代器。我检查每个键的选项乘积 (for values_option in product(*parameter.values())) 并使用原始键创建一个新字典)
from itertools import product
import numpy as np
parameter={'alpha1':np.linspace(0.3,0.4,10),'alpha2':np.linspace(0.9,2,100)}
def parameter_options(parameter):
for values_option in product(*parameter.values()):
yield dict(zip(parameter.keys(), values_option))
for opt in parameter_options(parameter):
print opt
让我们一块一块地看:
parameter.values()
这给出了字典中每个键值对值的列表。
例如,如果我们有dictionary = {a: (1, 2, 3), b: (4, 5, 6)},使用dictionary.values() 将返回[(1, 2, 3), (4, 5, 6)]。执行dictionary.keys() 将得到['a', 'b']。
注意:Python 2 和 Python 3 之间存在差异 - 在 Python 2 中,这些方法(keys() 和 values())将返回普通列表,而在 Python 3 中它们返回一个特殊的列表迭代器。这不应该改变解决方案。
product(*parameter.values())
我们使用星号来“解包”列表。简单地说,itertools.product 接收任意数量的参数。我们想使用所有的values 作为输入:
vals = parameter.values()
product(vals[0], vals[1], vals[2], ..., vals[len(vals)])
Python 有一种简单的方法可以将列表作为输入传递给接收任意数量参数的函数。最后一行与product(*vals) 相同。
for values_option in product(*parameter.values()):
我们检查了parameter 字典值的所有选项。
第一次迭代将为所有参数提供第一个选项。第二次迭代将为除一个参数之外的所有参数提供第一个选项,该参数将具有第二个选项。这一直持续到我们有最后一个选项,每个参数都有它的最后一个选项。
zip(parameter.keys(), values_option)
这需要两个列表(键和可能的值)并基本上转置它们。它给出了一个相同长度的列表,其中包括对:第一个列表中的第一个元素和第二个列表中的第二个元素。像这样:
keys = ['a', 'b', 'c', 'd']
vals = [1, 2, 3, 4]
zip(keys, vals) = [('a', 1), ('b', 2), ('c', 3), ('d', 4)]
dict(...)
现在我们可以使用这个压缩列表来创建字典。这是启动 dict 的另一种方式
{'a': 1, 'b': 2, 'c': 3} == dict([('a', 1), ('b', 2), ('c', 3)])
yield ...
这就是我们在 python 中用来创建迭代器的方法。这是一个复杂的主题,但您可以在 for 循环之前写下这一行
options = []
而不是yield dict(...) 写options.append(dict(...))。
并在函数的末尾return options。
瞧。