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



我想将字典中的所有值组合为多个字典(每个字典都包含原始值的每个键,但只有一个值的一个值)。说我想用以下方式参数函数调用:

kwargs = {'a': [1, 2, 3], 'b': [1, 2, 3]}

我如何获得这样的所有组合的列表:

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}]

原始 kwargs中可能有大量的键,每个值都被认为是一个值得的键,但值的数量未固定。

如果可能的话:最终combinations应该是发电机(不是列表)。

您可以将 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)]]

然后,您可以像这样使用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}]

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}

只是另一种方式,首先构建值元组,然后与键结合(几乎与 @thefourtheye的方式相反: - )。

>>> combinations = (dict(zip(kwargs, vs)) for vs in product(*kwargs.values()))
>>> for c in combinations:
        print(c)
{'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}

最新更新