在保留相同键的同时获取字典中列表的乘积

Get the product of lists inside a dict while retaining the same keys

我有以下字典:

my_dict = {'A': [1, 2], 'B': [1, 4]}

我想以这样的字典列表结束:

[
    {'A': 1, 'B': 1},
    {'A': 1, 'B': 4},
    {'A': 2, 'B': 1},
    {'A': 2, 'B': 4}
]

所以,我正在寻找字典列表的产品,表示为使用与传入字典相同的键的字典列表。

我得到的最接近的是:

my_dict = {'A': [1, 2], 'B': [1, 4]}
it = []
for k in my_dict.keys():
    current = my_dict.pop(k)
    for i in current:
        it.append({k2: i2 for k2, i2 in my_dict.iteritems()})
        it[-1].update({k: i})

这除了看起来很丑外,并没有给我想要的东西:

[
    {'A': 1, 'B': [1, 4]}, 
    {'A': 2, 'B': [1, 4]}, 
    {'B': 1}, 
    {'B': 4}
]

如果有人想解谜,我很想看看你是如何解决的。

试试这个:

from itertools import product

def dict_product(values, first, second):
   return [
       {first: first_value, second: second_value}
       for first_value, second_value in product(values[first], values[second])
   ]

这是结果:

>>> dict_product({'A': [1, 2], 'B': [1, 4]}, 'A', 'B')
[{'A': 1, 'B': 1}, {'A': 1, 'B': 4}, {'A': 2, 'B': 1}, {'A': 2, 'B': 4}]

您可以使用 itertools.product for this, i.e calculate cartesian product of the value and then simply zip each of the them with the keys from the dictionary. Note that ordering of a dictkeys() 和相应的 values() 如果中间没有修改,则保持不变,因此这里的排序不是问题:

>>> from itertools import product
>>> my_dict = {'A': [1, 2], 'B': [1, 4]}
>>> keys = list(my_dict)
>>> [dict(zip(keys, p)) for p in product(*my_dict.values())]
[{'A': 1, 'B': 1}, {'A': 1, 'B': 4}, {'A': 2, 'B': 1}, {'A': 2, 'B': 4}]

您可以在列表理解中使用 itertools.product 函数:

>>> from itertools import product
>>> [dict(i) for i in product(*[[(i,k) for k in j] for i,j in my_dict.items()])]
[{'A': 1, 'B': 1}, {'A': 1, 'B': 4}, {'A': 2, 'B': 1}, {'A': 2, 'B': 4}]

您可以通过以下列表理解得到包含您的键和值的对:

[(i,k) for k in j] for i,j in my_dict.items()]
[[('A', 1), ('A', 2)], [('B', 1), ('B', 4)]]

然后你可以使用product计算前面列表的乘积,然后用dict函数将它们转换成字典。

使用 itertools:

>>> from itertools import product
>>> my_dict = {'A': [1, 2], 'B': [1, 4]}
>>> keys, items = zip(*my_dict.items())
>>> [dict(zip(keys, x)) for x in product(*items)]
[{'A': 1, 'B': 1}, {'A': 1, 'B': 4}, {'A': 2, 'B': 1}, {'A': 2, 'B': 4}]