获取dict中的列表产品,同时保留相同的键

时间:2015-03-27 22:19:19

标签: python list dictionary product

我有以下词典:

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

我想最终得到一份像这样的词典:

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

所以,我是在dict的列表产品之后,表达为使用与传入词典相同的键的词典列表。

我最接近的是:

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

如果有人想要解决一个谜语,我很乐意看到你是如何接近它的。

4 个答案:

答案 0 :(得分:8)

你可以使用itertools.product,即计算值的笛卡尔积,然后用字典中的键将它们拉上每个。请注意,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}]

答案 1 :(得分:1)

你可以在列表理解中使用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函数将它们转换为字典。

答案 2 :(得分:1)

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

答案 3 :(得分:0)

试试这个:

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