列表字典的笛卡尔积

问题描述 投票:3回答:4

我有一个以下形式的字典:

{
    'variable_1': [a1, b1, c1],
    'variable_2': [a2, b2, c2],
    'variable_3': [a3, b3, c3],
    ...
}

(这本词典中有n条目)

我有一个问题,我想获得不同值的所有可能组合,例如:

[(a1, a2, a3), (b1, a2, a3), (c1, a2, a3), (a1, b2, a3), ...]

我知道这可以用itertools的笛卡儿产品来完成。但是,我注意到如果结果是以下形式,我的问题会容易得多:

[{'variable1': a1, 'variable2':a2, 'variable3': a3}, {'variable1': b1, 'variable2':a2, 'variable3': a3}, ...]

有一个简单的方法吗?

python cartesian-product
4个回答
0
投票
import itertools
d = {
'variable_1': ['a1', 'b1', 'c1'],
'variable_2': ['a2', 'b2', 'c2'],
'variable_3': ['a3', 'b3', 'c3'],
}


keys = (list(d.keys())) # ['variable_1', 'variable_2', 'variable_3']
values = (list(itertools.product(*(list(d.values()))))) #[('a1', 'a2', 'a3'), ('a1', 'a2', 'b3'), ('a1', 'a2', 'c3')...]

dictionary = []
for val in values:
    dictionary.append(dict(zip(keys, val)))

输出:

[{'variable_1': 'a1', 'variable_2': 'a2', 'variable_3': 'a3'}, {'variable_1': 'a1', 'variable_2': 'a2', 'variable_3': 'b3'}, {'variable_1': 'a1', 'variable_2': 'a2', 'variable_3': 'c3'}, {'variable_1': 'a1', 'variable_2': 'b2', 'variable_3': 'a3'},...]

例:

d = {
'variable_1': ['a1', 'b1', 'c1','d1'],
'variable_2': ['a2', 'b2', 'c2','d2'],
'variable_3': ['a3', 'b3', 'c3','d3'],
'variable_4': ['a3', 'b3', 'c3','d4'],
}

输出:

[{'variable_1': 'a1', 'variable_2': 'a2', 'variable_3': 'a3', 'variable_4': 'a3'}, {'variable_1': 'a1', 'variable_2': 'a2', 'variable_3': 'a3', 'variable_4': 'b3'}, {'variable_1': 'a1', 'variable_2': 'a2', 'variable_3': 'a3', 'variable_4': 'c3'}, {'variable_1': 'a1', 'variable_2': 'a2', 'variable_3': 'a3', 'variable_4': 'd4'}, ...]

0
投票

你还需要itertools.product

a = {'v1': [1,2], 'v2': [3,4]}
gen = (dict(zip(a.keys(), x)) for x in itertools.product(*a.values()))
>>> list(gen)
[{'v1': 1, 'v2': 3}, {'v1': 1, 'v2': 4}, {'v1': 2, 'v2': 3}, {'v1': 2, 'v2': 4}]

您可以从右到左阅读生成器:

>>> list(itertools.product(*a.values()))
[(1, 3), (1, 4), (2, 3), (2, 4)]
  • 然后使用zip制作成对的键和产品的结果。
>>> zip(['v1', 'v2'], [1, 3])
[('v1', 1), ('v2', 3)]
  • 最后从那对再次建立一个字典
>>> dict([('v1', 1), ('v2', 3)])
{'v1': 1, 'v2': 3}

0
投票

您还可以使用递归函数来实现无导入解决方案:

def combo(data, c=[]):
  if not data:
    yield c
  else:
    for i in data[0]:
      yield from combo(data[1:], c+[i])

d = {'variable_1': ['a1', 'b1', 'c1'], 'variable_2': ['a2', 'b2', 'c2'], 'variable_3': ['a3', 'b3', 'c3']} 
keys, values = zip(*d.items())
result = [dict(zip(keys, i)) for i in combo(values)]

输出:

[{'variable_1': 'a1', 'variable_2': 'a2', 'variable_3': 'a3'}, {'variable_1': 'a1', 'variable_2': 'a2', 'variable_3': 'b3'}, {'variable_1': 'a1', 'variable_2': 'a2', 'variable_3': 'c3'}, {'variable_1': 'a1', 'variable_2': 'b2', 'variable_3': 'a3'}, {'variable_1': 'a1', 'variable_2': 'b2', 'variable_3': 'b3'}, {'variable_1': 'a1', 'variable_2': 'b2', 'variable_3': 'c3'}, {'variable_1': 'a1', 'variable_2': 'c2', 'variable_3': 'a3'}, {'variable_1': 'a1', 'variable_2': 'c2', 'variable_3': 'b3'}, {'variable_1': 'a1', 'variable_2': 'c2', 'variable_3': 'c3'}, {'variable_1': 'b1', 'variable_2': 'a2', 'variable_3': 'a3'}, {'variable_1': 'b1', 'variable_2': 'a2', 'variable_3': 'b3'}, {'variable_1': 'b1', 'variable_2': 'a2', 'variable_3': 'c3'}, {'variable_1': 'b1', 'variable_2': 'b2', 'variable_3': 'a3'}, {'variable_1': 'b1', 'variable_2': 'b2', 'variable_3': 'b3'}, {'variable_1': 'b1', 'variable_2': 'b2', 'variable_3': 'c3'}, {'variable_1': 'b1', 'variable_2': 'c2', 'variable_3': 'a3'}, {'variable_1': 'b1', 'variable_2': 'c2', 'variable_3': 'b3'}, {'variable_1': 'b1', 'variable_2': 'c2', 'variable_3': 'c3'}, {'variable_1': 'c1', 'variable_2': 'a2', 'variable_3': 'a3'}, {'variable_1': 'c1', 'variable_2': 'a2', 'variable_3': 'b3'}, {'variable_1': 'c1', 'variable_2': 'a2', 'variable_3': 'c3'}, {'variable_1': 'c1', 'variable_2': 'b2', 'variable_3': 'a3'}, {'variable_1': 'c1', 'variable_2': 'b2', 'variable_3': 'b3'}, {'variable_1': 'c1', 'variable_2': 'b2', 'variable_3': 'c3'}, {'variable_1': 'c1', 'variable_2': 'c2', 'variable_3': 'a3'}, {'variable_1': 'c1', 'variable_2': 'c2', 'variable_3': 'b3'}, {'variable_1': 'c1', 'variable_2': 'c2', 'variable_3': 'c3'}]
© www.soinside.com 2019 - 2024. All rights reserved.