如何在python中为所有可能的参数组合编写递归函数

时间:2015-05-10 18:17:05

标签: python recursion combinations

我正在尝试编写一段代码来遍历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嵌套for循环。任何人都可以给出一个关于如何编写递归函数的演示,以给出参数的所有可能组合的列表? 感谢

1 个答案:

答案 0 :(得分:2)

您可以使用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(...)

现在我们可以使用此压缩列表来创建字典。这是启动词典的另一种方式

{'a': 1, 'b': 2, 'c': 3} == dict([('a', 1), ('b', 2), ('c', 3)])

<强> yield ...

这是我们在python中用来创建迭代器的方法。这是一个复杂的主题,但您可以在for循环此行

之前编写
options = []

而不是yield dict(...)options.append(dict(...))。 并在函数return options的末尾。

瞧。