繁体   English   中英

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

[英]How to turn a list of dictionaries of lists into a list of lists of dictionaries for each combination

我想定义 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'}]]

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

这是我想出的:

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

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM