如何将列表的字典列表转换为每个组合的字典列表的列表



我想定义一个python函数,它接受一个字典列表,其中一些键可以是列表,然后返回一个字典列表的列表,其中每个键是一个值,对应于所有选项的组合(一个选项是从每个列表中选择一个值)。

考虑以下输入:

input = [
{
"name": "A",
"option1": [1, 2],
"option2": ["a1", "a2"]
}
{
"name": "B",
"option1": [3, 4],
"option2": "b1"
}
]

给定这个输入,期望的输出将是:

output = [[{"name": "A", "option1": 1, "option2": "a1"}{"name": "B", "option1": 3, "option2": "b1"}]
[{"name": "A", "option1": 1, "option2": "a1"}{"name": "B", "option1": 4, "option2": "b1"}]
[{"name": "A", "option1": 1, "option2": "a2"}{"name": "B", "option1": 3, "option2": "b1"}]
[{"name": "A", "option1": 1, "option2": "a2"}{"name": "B", "option1": 4, "option2": "b1"}]
[{"name": "A", "option1": 2, "option2": "a1"}{"name": "B", "option1": 3, "option2": "b1"}]
[{"name": "A", "option1": 2, "option2": "a1"}{"name": "B", "option1": 4, "option2": "b1"}]
[{"name": "A", "option1": 2, "option2": "a2"}{"name": "B", "option1": 3, "option2": "b1"}]
[{"name": "A", "option1": 2, "option2": "a2"}{"name": "B", "option1": 4, "option2": "b1"}]]

让我们试一下。

import itertools 

input = [
{
"name": "A",
"option1": [1, 2],
"option2": ["a1", "a2"]
},
{
"name": "B",
"option1": [3, 4],
"option2": "b1"
}
]
list_opts = [y 
for x in input 
for y in [x['option1'] 
if type(x['option1']) == list 
else [x['option1']], 
x['option2'] 
if type(x['option2']) == list 
else [x['option2']]]]
list_combinations = list(itertools.product(*list_opts))
output = [[{"name": "A", 
"option1": x[0], 
"option2": x[1]}, 
{"name": "B", 
"option1": x[2], 
"option2": x[3]}] 
for x in list_combinations]

这是我得到的。

[[{'name': 'A', 'option1': 1, 'option2': 'a1'},
{'name': 'B', 'option1': 3, 'option2': 'b1'}],
[{'name': 'A', 'option1': 1, 'option2': 'a1'},
{'name': 'B', 'option1': 4, 'option2': 'b1'}],
[{'name': 'A', 'option1': 1, 'option2': 'a2'},
{'name': 'B', 'option1': 3, 'option2': 'b1'}],
[{'name': 'A', 'option1': 1, 'option2': 'a2'},
{'name': 'B', 'option1': 4, 'option2': 'b1'}],
[{'name': 'A', 'option1': 2, 'option2': 'a1'},
{'name': 'B', 'option1': 3, 'option2': 'b1'}],
[{'name': 'A', 'option1': 2, 'option2': 'a1'},
{'name': 'B', 'option1': 4, 'option2': 'b1'}],
[{'name': 'A', 'option1': 2, 'option2': 'a2'},
{'name': 'B', 'option1': 3, 'option2': 'b1'}],
[{'name': 'A', 'option1': 2, 'option2': 'a2'},
{'name': 'B', 'option1': 4, 'option2': 'b1'}]]

虽然George的答案可能产生正确的输出,但如果将解决方案扩展到更多选项,则可能出现问题。

这是我想到的:

import copy
import itertools
input = [
{
"name": "A",
"option1": [1, 2],
"option2": ["a1", "a2"]
},
{
"name": "B",
"option1": [3, 4],
"option2": "b1"
}
]
def dictContainsListVals(dic):
return any([isinstance(val, list) for val in dic.values()])
def splitDict(dic):
flattenedDicts = [dic]
while any(dictContainsListVals(dic) for dic in flattenedDicts):
splitDict = flattenedDicts.pop(0)
for key, value in splitDict.items():
if isinstance(value, list):
for el in value:
dictCopy = copy.deepcopy(splitDict)
dictCopy[key] = el
flattenedDicts.append(dictCopy)
break
else:
flattenedDicts.append(splitDict)
return flattenedDicts
flattenedDicts = []
for dic in input:
flattenedDicts.append(splitDict(dic))
output = itertools.product(*flattenedDicts)
print(list(output))

输出:

[({'name': 'A', 'option1': 1, 'option2': 'a1'}, {'name': 'B', 'option1': 3, 'option2': 'b1'}), 
({'name': 'A', 'option1': 1, 'option2': 'a1'}, {'name': 'B', 'option1': 4, 'option2': 'b1'}), 
({'name': 'A', 'option1': 1, 'option2': 'a2'}, {'name': 'B', 'option1': 3, 'option2': 'b1'}), 
({'name': 'A', 'option1': 1, 'option2': 'a2'}, {'name': 'B', 'option1': 4, 'option2': 'b1'}), 
({'name': 'A', 'option1': 2, 'option2': 'a1'}, {'name': 'B', 'option1': 3, 'option2': 'b1'}), 
({'name': 'A', 'option1': 2, 'option2': 'a1'}, {'name': 'B', 'option1': 4, 'option2': 'b1'}), 
({'name': 'A', 'option1': 2, 'option2': 'a2'}, {'name': 'B', 'option1': 3, 'option2': 'b1'}), 
({'name': 'A', 'option1': 2, 'option2': 'a2'}, {'name': 'B', 'option1': 4, 'option2': 'b1'})]

相关内容

  • 没有找到相关文章

最新更新