我正在尝试编写一块代码,以遍历带有Python算法的所有可能参数组合。
import numpy as np
parameter={'alpha1':np.linspace(0.3,0.4,10),'alpha2':np.linspace(0.9,2,100),...'alpha5':np.linspace(5,10,100)}
问题在于我无法为循环编写5个纽扣。有人可以为如何编写递归功能提供演示以提供参数的所有可能组合的列表吗?谢谢
您可以使用itertools.product
函数,该函数获取迭代列表并创建其笛卡尔产品的迭代器(请参阅文档)。
在我的解决方案中,我将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(...)
现在,我们可以使用此Zipped列表来创建字典。这是启动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
。
voila。