Python:如何创建具有动态参数数量的参数网格

Python: how to create a parameter grid with dynamic number of parameters

假设为感兴趣的参数范围提供了一个字典,其中包含每个感兴趣的参数的范围:

G = {'a': [1,2], 'b': [3], 'c': [1, 2.5] }

目标是提取此网格上的每个参数配置。上例中有4个这样的,对应2个a的值,2个b的值:

G1 = {'a': 1, 'b': 3, 'c': 1 }
G2 = {'a': 2, 'b': 3, 'c': 1 }
G3 = {'a': 1, 'b': 3, 'c': 2.5 }
G4 = {'a': 2, 'b': 3, 'c': 2.5 }

编写两个嵌套的 for 循环来生成所有此类配置很简单,当 G.[=19 中的列表数量可变时,对于一般情况如何做到这一点就变得不那么简单了=]

我想到的唯一解决方案是创建一个与参数数量一样长的多索引向量 vec=[0,0],并递增以迭代所有可能的配置:[0,0] -> [1,0] -> [0,1] -> [1,1] :

G = {'a': [1,2], 'b': [3], 'c': [1, 2.5] }

def get_configs(G):
    keys = list(G.keys())
    lists = list(G.values())
    sizes = [len(l) for l in lists]
    num_confs = np.prod(sizes)
    index = [0]*(len(G)+1)
    configs = []
    while len(configs)<num_confs:
        configs.append( {keys[i]: lists[i][index[i]] for i in range(len(G))})
        index[0] += 1
        cur = 0
        while len(configs)<num_confs and index[cur]>=sizes[cur]:
             index[cur]=0
             cur += 1
             index[cur] += 1
        return configs

configs = get_configs(G)
print(configs)

但是,解决方案似乎有点过于复杂和难看。是否有使用 python 的干净解决方案?

这是一个使用 itertools.product 的通用实现:

from itertools import product

def dict_configs(d):
    for vcomb in product(*d.values()):
        yield dict(zip(d.keys(), vcomb))

用法:

>>> G = {'a': [1,2], 'b': [3], 'c': [1, 2.5] }
>>> for config in dict_configs(G):
...     print(config)
...
{'a': 1, 'b': 3, 'c': 1}
{'a': 1, 'b': 3, 'c': 2.5}
{'a': 2, 'b': 3, 'c': 1}
{'a': 2, 'b': 3, 'c': 2.5}