Объединение двух словарей в словарь словарей в Python - PullRequest
0 голосов
/ 16 декабря 2018

У меня есть словарь по умолчанию из библиотеки коллекций, который представляет список всех соединений каждого узла графа:

edges = {1 : [987, 682, 465], 
         2 : [45, 67, 85, 907, ...],
         ...
         n : [32, 563, 659, 902]}

И у меня есть еще один словарь, который хранит для каждого узлакатегория, к которой он принадлежит, вот так:

categories = {1 : ['category1', 'category37'], 
              2 : ['category45', 'category86', ...],
             ... , 
              n : ['category1','category2'], ....}

Я хотел бы получить окончательный словарь, который включает в себя для каждой категории словарь всех соединений этой категории, он будет выглядеть так:

final = {'category1' : {1 : [987, 682, 465], 37: [84, 777, 90, 744, 343], ...},
         'category2' : {37 : [84, 777, 90, 744, 343], 64: [32, 1222], ...}
          ...}

Ответы [ 3 ]

0 голосов
/ 16 декабря 2018

Задача может быть выполнена следующим образом:

  1. Создать промежуточный словарь, ключами которого являются категории: categoryX, а значения - это список ребер, попадающих под categoryX
  2. Создайте окончательный словарь, ключами которого являются категории: categoryX и соответствующие значения - это словарь ребер, попадающих под categoryX

Мы используем встроенный defaultdict, чтобы упростить созданиепромежуточный словарь

from collections import defaultdict


edges = {1 : [987, 682, 465],
         2 : [45, 67, 85, 907],
         3 : [32, 563, 659, 902]}

categories = {1 : ['category1', 'category37'],
              2 : ['category45', 'category86'],
              3 : ['category1', 'category2']}

intermediate = defaultdict(list)
for k, v in categories.items():
    for c in v:
        intermediate[c].append(k)


final = defaultdict(dict)

for k, v in intermediate.items():
    final[k] = {i:edges[i] for i in v}

Мы также можем создать final с пониманием списка следующим образом:

last = {k: {i : edges[i] for i in v} for k, v in intermediate.items()}

Пример выполнения:

>>> from pprint import pprint
>>> pprint(final)
defaultdict(<class 'dict'>,
            {'category1': {1: [987, 682, 465], 3: [32, 563, 659, 902]},
             'category2': {3: [32, 563, 659, 902]},
             'category37': {1: [987, 682, 465]},
             'category45': {2: [45, 67, 85, 907]},
             'category86': {2: [45, 67, 85, 907]}})

>>> pprint(last)
{'category1': {1: [987, 682, 465], 3: [32, 563, 659, 902]},
 'category2': {3: [32, 563, 659, 902]},
 'category37': {1: [987, 682, 465]},
 'category45': {2: [45, 67, 85, 907]},
 'category86': {2: [45, 67, 85, 907]}}

Использование промежуточного словаТаблица - это отличный способ гибко выполнять поиск по сложному набору данных / таблице, связывать таблицы и легко создавать новые таблицы.

0 голосов
/ 16 декабря 2018

Python dict не имеет .append() метода (но list), вам нужно: .update()

Если вы хотите использовать цикл for, вы можете попробовать

# Example using for-loop
edges = {
    1: [1, 11], 
    2: [2, 222], 
    3: [33], 
    4: [4, 4444, 44]}
categories = {
    1: ['category1'], 
    2: ['category2', 'category3'], 
    3: ['category1', 'category4']}

final = {} 
for key, value in categories.items():
    final['category{}'.format(key)] = {}
    for x in value:
        edge_key = int(x.replace('category', ''))
        final['category{}'.format(key)].update({edge_key: edges[edge_key]})
>>> print(final)
# Output
# {'category2': {2: [2, 222], 3: [33]}, 'category1': {1: [1, 11]}, 'category3': {1: [1, 11], 4: [4, 4444, 44]}}
0 голосов
/ 16 декабря 2018

Для этого можно использовать вложенные циклы.

Однострочная версия:

final = {category: {edge: edges[edge]} for edge in edges \
         for category in categories[edge] if category in categories[edge]}

Подробная версия с четкими шагами:

final = {}
for edge in edges:  # loop through each edge
    # find all categories that belong to the current edge in outer loop and then append 
    # the edge list to the corresponding category in the final dictionary
    for category in categories[edge]:
        if category in final:
            final[category][edge] = edges[edge]
        else:
            final[category] = {edge: edges[edge]}

Чтобы проверить это,Я составил пример.

edges = {1:[11,56,3], 2:[69,4,5,6], 3:[1,8,96,5]}
categories = {1:['category1', 'category37'],2:['category45', 'category86'],3:['category1','category2']}

Результат -

{'category1': {1: [11, 56, 3], 3: [1, 8, 96, 5]},
 'category37': {1: [11, 56, 3]},
 'category45': {2: [69, 4, 5, 6]},
 'category86': {2: [69, 4, 5, 6]},
 'category2': {3: [1, 8, 96, 5]}}
...