简体   繁体   English

合并基于公共键值但具有列表嵌套字典的字典列表

[英]Merging a list of dictionaries based on common key values but with nested dict of lists

Trying to wrap my head around (what I feel) is a way too complicated dict/list to represent the relationship between items.试图绕开我的头(我的感觉)是一种过于复杂的 dict/list 来表示项目之间的关系。

mappings = [{'switches': ['switch1', 'switch2'], 'relationships': [{'compute_name': 'compute001', 'servers': ['server1', 'server2']}]},
            {'switches': ['switch1', 'switch2'], 'relationships': [{'compute_name': 'compute002', 'servers': ['server3', 'server4']}]},
            {'switches': ['switch3', 'switch4'], 'relationships': [{'compute_name': 'compute003', 'servers': ['server5', 'server6']}]},
            {'switches': ['switch3', 'switch4'], 'relationships': [{'compute_name': 'compute004', 'servers': ['server7', 'server8', 'server9']}]},
            {'switches': ['switch5', 'switch6'], 'relationships': [{'compute_name': 'compute005', 'servers': ['server10', 'server11', 'server12']}]},
            {'switches': ['switch5', 'switch6'], 'relationships': [{'compute_name': 'compute006', 'servers': ['server13', 'server14', 'server15', 'server16']}]}]

As you can see, it's a list of dict, where the value is sometimes another list of dict.如您所见,它是一个 dict 列表,其中值有时是另一个 dict 列表。

The issue I'm having is that the starting data are holding "duplicates".我遇到的问题是起始数据持有“重复”。 For example, if you look at the key value of "switches", you can see that the list holding "switch1" + "switch2" are present twice.例如,如果您查看“switches”的键值,您可以看到包含“switch1”+“switch2”的列表出现了两次。 It's valid as the relationship data is unique.它是有效的,因为关系数据是唯一的。

I would like to find a way to transform that dict into something like the following:我想找到一种方法将该 dict 转换为如下内容:

end_mapping = [{'switches': ['switch1', 'switch2'], 'relationships': [{'compute_name': 'compute001', 'servers': ['server1', 'server2']},
                                                                      {'compute_name': 'compute002', 'servers': ['server3', 'server4']}]},
               {'switches': ['switch3', 'switch4'], 'relationships': [{'compute_name': 'compute003', 'servers': ['server5', 'server6']},
                                                                      {'compute_name': 'compute004', 'servers': ['server7', 'server8', 'server9']}]},
               {'switches': ['switch5', 'switch6'], 'relationships': [{'compute_name': 'compute005', 'servers': ['server10', 'server11', 'server12']},
                                                                      {'compute_name': 'compute006', 'servers': ['server13', 'server14', 'server15', 'server16']}]}
              ]

In this data set, the switches key values are unique and I've "merged" the relationships dictionaries.在这个数据集中,开关键值是唯一的,我已经“合并”了关系字典。

I've been banging my head around this but haven't found a way so far.我一直在努力解决这个问题,但到目前为止还没有找到方法。

I have a starting point with:我有一个起点:

new_list_of_dict = []
for mapping_dict_a in mappings:
    for mapping_dict_b in mappings:
        if set(mapping_dict_b['switches']) == set(mapping_dict_a['switches']):
            same = True
            mapping_dict_a['relationships'].append(mapping_dict_b['relationships'])
            new_list_of_dict.append(mapping_dict_a)
            break
        else:
            same = False
            print('NOT SAME!')

But it's not working so far (I'm sure it's wrong;) - and I end up with either an infinite loop or way too much data in the final_dict.但到目前为止它还没有工作(我确定它是错误的;) - 我最终得到一个无限循环或 final_dict 中的数据太多。

Any tips?有小费吗?

Thanks!谢谢!

Hey so I came up with something that should work, though it is a hack.嘿,所以我想出了一些应该可以工作的东西,尽管它是一个 hack。 Let me know how it goes.让我知道事情的后续。

# given the mappings var you provided in your example:
switches = [item.get('switches') for item in mappings]
unique_switches = [list(x) for x in set(tuple(x) for x in switches)]

unique_mapping = []
for switch in unique_switches:
    relationship_list = []
    for item in mappings:
        if item.get('switches') == switch:
            relationship_list.append(item['relationships'])
    unique_mapping.append({'switches': switch, 'relationships': relationship_list})

unique_mapping should result in: unique_mapping应导致:

[{'switches': ['switch5', 'switch6'],
  'relationships': [[{'compute_name': 'compute005',
     'servers': ['server10', 'server11', 'server12']}],
   [{'compute_name': 'compute006',
     'servers': ['server13', 'server14', 'server15', 'server16']}]]},
 {'switches': ['switch1', 'switch2'],
  'relationships': [[{'compute_name': 'compute001',
     'servers': ['server1', 'server2']}],
   [{'compute_name': 'compute002', 'servers': ['server3', 'server4']}]]},
 {'switches': ['switch3', 'switch4'],
  'relationships': [[{'compute_name': 'compute003',
     'servers': ['server5', 'server6']}],
   [{'compute_name': 'compute004',
     'servers': ['server7', 'server8', 'server9']}]]}]

Here is a way usingfrozenset & why frozenset not set refer this post unhashable type: 'set'这是一种使用frozenset的方法以及为什么未set frozenset参考这篇文章unhashable type: 'set'

results = {}

for v in mappings:
    key = frozenset(v['switches'])

    if results.get(key):
        results[key]['relationships'].append(v['relationships'])
    else:
        results[key] = v

print(list(results.values()))
[{'relationships': [{'compute_name': 'compute001',
                     'servers': ['server1', 'server2']},
                    [{'compute_name': 'compute002',
                      'servers': ['server3', 'server4']}]],
  'switches': ['switch1', 'switch2']},
...
}]

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

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