爆炸词典 - 获取词典中所有值的组合

MSe*_*ert 4 python dictionary cartesian-product

我希望将字典中值的所有组合作为多个字典(每个字典包含原始的每个键但只包含原始值的一个值).假设我想通过以下方式参数化函数调用:

kwargs = {'a': [1, 2, 3], 'b': [1, 2, 3]}
Run Code Online (Sandbox Code Playgroud)

如何获得所有组合的列表,如下所示:

combinations = [{'a': 1, 'b': 1}, {'a': 1, 'b': 2}, {'a': 1, 'b': 3},
                {'a': 2, 'b': 1}, {'a': 2, 'b': 2}, {'a': 2, 'b': 3},
                {'a': 3, 'b': 1}, {'a': 3, 'b': 2}, {'a': 3, 'b': 3}]
Run Code Online (Sandbox Code Playgroud)

原始中可以有任意数量的密钥,kwargs并且每个值都是可迭代的,但值的数量不固定.

如果可能:final combinations应该是一个生成器(不是列表).

the*_*eye 9

你可以把kwargs这样的东西弄平

>>> kwargs = {'a': [1, 2, 3], 'b': [1, 2, 3]}
>>> flat = [[(k, v) for v in vs] for k, vs in kwargs.items()]
>>> flat
[[('b', 1), ('b', 2), ('b', 3)], [('a', 1), ('a', 2), ('a', 3)]]
Run Code Online (Sandbox Code Playgroud)

然后,你可以itertools.product像这样使用

>>> from itertools import product
>>> [dict(items) for items in product(*flat)]
[{'a': 1, 'b': 1},
 {'a': 2, 'b': 1},
 {'a': 3, 'b': 1},
 {'a': 1, 'b': 2},
 {'a': 2, 'b': 2},
 {'a': 3, 'b': 2},
 {'a': 1, 'b': 3},
 {'a': 2, 'b': 3},
 {'a': 3, 'b': 3}]
Run Code Online (Sandbox Code Playgroud)

itertools.product实际上返回一个迭代器.因此,您可以按需获取值并构建您的词典.或者你可以使用map,它也返回一个迭代器.

>>> for item in map(dict, product(*flat)):
...     print(item)
...
...
{'b': 1, 'a': 1}
{'b': 1, 'a': 2}
{'b': 1, 'a': 3}
{'b': 2, 'a': 1}
{'b': 2, 'a': 2}
{'b': 2, 'a': 3}
{'b': 3, 'a': 1}
{'b': 3, 'a': 2}
{'b': 3, 'a': 3}
Run Code Online (Sandbox Code Playgroud)