如何根据源字典中值的笛卡尔积创建一个字典列表("展开"字典)?

30
给出这样一个字典:
{
    'Color': ['Red', 'Yellow'],
    'Size': ['Small', 'Medium', 'Large']
}

如何创建一个字典列表,将第一个字典的各个键的值组合起来?我想要的是:
[
    {'Color': 'Red', 'Size': 'Small'},
    {'Color': 'Red', 'Size': 'Medium'},
    {'Color': 'Red', 'Size': 'Large'},
    {'Color': 'Yellow', 'Size': 'Small'},
    {'Color': 'Yellow', 'Size': 'Medium'},
    {'Color': 'Yellow', 'Size': 'Large'}
]

如果你展示出你所尝试过的,那么这会是一个好问题。 - msvalkon
4
无论如何,我认为这是一个好问题,因为在这里想出正确的概念并不容易。 - Tim Pietzcker
2个回答

49
我认为你想要笛卡尔积,而不是排列,此时itertools.product可以帮助:
>>> from itertools import product
>>> d = {'Color': ['Red', 'Yellow'], 'Size': ['Small', 'Medium', 'Large']}
>>> [dict(zip(d, v)) for v in product(*d.values())]
[{'Color': 'Red', 'Size': 'Small'}, {'Color': 'Red', 'Size': 'Medium'}, {'Color': 'Red', 'Size': 'Large'}, {'Color': 'Yellow', 'Size': 'Small'}, {'Color': 'Yellow', 'Size': 'Medium'}, {'Color': 'Yellow', 'Size': 'Large'}]

2
很好知道Python在zip().values()中以相同、可重复的顺序迭代字典项! - Tim Pietzcker
3
是的,这个属性已经记录在案,可以依赖它。顺序本身是任意的,但是没有符合规范的Python实现会违反这样一个保证:如果你不修改“d”,则d.keys()(这里是“d”)和d.values()必须匹配。 - DSM
谢谢!这很完美。 - idnavid
我认为自从Python 3.7版本开始,dict顺序也不再是随意的了!请参见此处 - Marti Nito

1
您可以通过以下方式获得该结果:

x={'Color': ['Red', 'Yellow'], 'Size': ['Small', 'Medium', 'Large']}
keys=x.keys()
values=x.values()

matrix=[]
for i in range(len(keys)):
     cur_list=[]
     for j in range(len(values[i])):
             cur_list.append({keys[i]: values[i][j]})
     matrix.append(cur_list)

y=[]
for i in matrix[0]:
     for j in matrix[1]:
             y.append(dict(i.items() + j.items()))

print y

结果:

[{'Color': 'Red', 'Size': 'Small'}, {'Color': 'Red', 'Size': 'Medium'}, {'Color': 'Red', 'Size': 'Large'}, {'Color': 'Yellow', 'Size': 'Small'}, {'Color': 'Yellow', 'Size': 'Medium'}, {'Color': 'Yellow', 'Size': 'Large'}]

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接