如何将列表的字典转换为包含所有组合的字典列表?

时间:2017-01-26 09:54:44

标签: python

基本上我要找的是相当于itertools.product但是dict s。

例如,假设我想为其关键字参数的所有组合测试一个函数,我想传递每个关键字参数的允许值列表,然后返回一个dicts列表。

kwargs_options = {"debug": ["on", "off"], 
                  "locale":["de_DE", "en_US", "fr_FR"]

预期产量:

[{'debug': 'on', 'locale': 'de_DE'},
 {'debug': 'on', 'locale': 'en_US'},
 {'debug': 'on', 'locale': 'fr_FR'},
 {'debug': 'off', 'locale': 'de_DE'},
 {'debug': 'off', 'locale': 'en_US'},
 {'debug': 'off', 'locale': 'fr_FR'}]

为了获得与itertools.product类似的API,这应返回一个迭代器,如果需要,可以通过调用list(...)来封装它。

示例电话:

list(dictproduct(kwargs_options}))

这与Combinations from dictionary with list values using Python类似,但返回两元素序列的列表,而不是两个单元素序列。

1 个答案:

答案 0 :(得分:3)

这就是我的想法:

from itertools import product

def dictproduct(dct):
    for t in product(*dct.itervalues()):
        yield dict(zip(dct.iterkeys(), t))

给了我们

>>> list(dictproduct({"debug":["on", "off"], "locale":["de_DE", "en_US", "fr_FR"]}))
[{'debug': 'on', 'locale': 'de_DE'},
 {'debug': 'on', 'locale': 'en_US'},
 {'debug': 'on', 'locale': 'fr_FR'},
 {'debug': 'off', 'locale': 'de_DE'},
 {'debug': 'off', 'locale': 'en_US'},
 {'debug': 'off', 'locale': 'fr_FR'}]

这也可用于有效地调用具有关键字参数的所有组合的函数:

def kwproduct(**kwargs):
    return dictproduct(kwargs)

def f(x, y):
    return 10*x + y

for kwargs in kwproduct(x=[1,2], y=[3,4,5]):
    print "f({x},{y})={z}".format(z=f(**kwargs), **kwargs)

输出:

f(1,3)=13
f(2,3)=23
f(1,4)=14
f(2,4)=24
f(1,5)=15
f(2,5)=25

kwproduct优于dictproduct的好处是您不需要创建dict,但它显然限制您使用有效的参数名称作为键。