Объединение списка словарей на основе общих значений ключей, но с вложенным dict списков - PullRequest
0 голосов
/ 10 июля 2020

Пытаться обернуть мою голову (что я чувствую) - это слишком сложный 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']}]}]

Как видите, это список dict, где значение иногда является другим списком dict.

Проблема, с которой я столкнулся, заключается в том, что исходные данные содержат «дубликаты». Например, если вы посмотрите на ключевое значение «переключателей», вы увидите, что список, содержащий «переключатель1» + «переключатель2», присутствует дважды. Это действительно так, поскольку данные отношения уникальны.

Я хотел бы найти способ преобразовать этот 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']}]}
              ]

В этом наборе данных значения ключей переключателей уникальны, и я "объединил" словари отношений.

Я ломал голову над этим, но пока не нашел способа.

У меня есть отправная точка с :

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!')

Но это пока не работает (я уверен, что это неправильно;) - и я получаю либо бесконечное l oop, либо слишком много данных в final_dict.

Есть подсказки?

Спасибо!

Ответы [ 2 ]

1 голос
/ 10 июля 2020

Привет, я придумал кое-что, что должно работать, хотя это хакерство. Сообщите мне, как это происходит.

# 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 должно привести к:

[{'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']}]]}]
0 голосов
/ 10 июля 2020

Вот способ использования frozenset и почему frozenset не set см. Этот пост 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']},
...
}]
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...