Объединить похожие значения вложенного dict в новый вложенный dict - PullRequest
0 голосов
/ 02 ноября 2018

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

d1 = {'Breda': {'Fuery': {'anger': 1},
                       'Havoc': {'anticipation': 1, 'surprise': 1},
                       'Hawkeye': {'anticipation': 2}},
             'Fuery': {'Breda': {'anticipation': 2, 'surprise': 1},
                       'Mustang': {'fear': 4}},
             'Havoc': {'Breda': {'joy': 1},
                       'Gloria': {'joy': 1},
                       'Hawkeye': {'anticipation': 4, 'joy': 1, 'surprise': 1},
                       'Mustang': {'surprise': 1}},
             'Hawkeye': {'Hawkeye': {'joy': 2, 'trust': 1},
                         'Mustang': {'anger': 1,
                                     'joy': 6,
                                     'surprise': 4,
                                     'trust': 1}},
             'Mustang': {'Everyone': {'anger': 2},
                         'Fuery': {'anger': 3, 'surprise': 1},
                         'Hawkeye': {'anger': 1,
                                     'joy': 6,
                                     'surprise': 1,
                                     'trust': 1},
                         'Mustang': {'joy': 2, 'trust': 1},
                         'the team': {'anger': 1}}}

Я пытаюсь создать из него новый вложенный dict d2, в котором новые ключи являются ключами самого внешнего dict d1, а затем значения каждого из этих ключей являются комбинацией значений. из всех внутренних d1 ключей.

Так, например, если 'anticipation' показывает более чем одну клавишу, значения 'anticipation' должны быть сложены вместе.

Желаемый вывод будет выглядеть так:

d2 = {'Breda': {'anger': 1, 'anticipation': 3, 'surprise': 1},
      'Fuery': {'anticipation': 2, 'surprise': 1, 'fear': 4},
      'Havoc': {'joy': 3, 'anticipation': 4, 'surprise': 2},
      'Hawkeye': {'joy': 8, 'trust': 2, 'anger': 1, 'surprise': 4}
      'Mustang': {'anger': 6, 'surprise': 2, 'joy': 8, 'trust': 2}}

Пока у меня есть этот код, который как-то не проходит через все ключи внутреннего dict и просто выводит значения последнего:

from pprint import pprint

      # see d1 above

d2 = dict()

for key, value in d1.items():

    for k, v in value.items():
        d2[key] = v

pprint(d2) 

Токовый выход:

{'Breda': {'anticipation': 2},
 'Fuery': {'fear': 4},
 'Havoc': {'surprise': 1},
 'Hawkeye': {'anger': 1, 'joy': 6, 'surprise': 4, 'trust': 1},
 'Mustang': {'anger': 1}}

Как мне перебрать все ключи внутреннего dict, а затем сравнить значения, чтобы сложить их вместе?

Я надеюсь, что мой вопрос понятен.

Будем весьма благодарны за любые советы!

1 Ответ

0 голосов
/ 02 ноября 2018

Вы можете использовать Counter для значений внутренних словарей:

from collections import Counter

d1 = {'Breda': {'Fuery': {'anger': 1},
                'Havoc': {'anticipation': 1, 'surprise': 1},
                'Hawkeye': {'anticipation': 2}},
      'Fuery': {'Breda': {'anticipation': 2, 'surprise': 1},
                'Mustang': {'fear': 4}},
      'Havoc': {'Breda': {'joy': 1},
                'Gloria': {'joy': 1},
                'Hawkeye': {'anticipation': 4, 'joy': 1, 'surprise': 1},
                'Mustang': {'surprise': 1}},
      'Hawkeye': {'Hawkeye': {'joy': 2, 'trust': 1},
                  'Mustang': {'anger': 1,
                              'joy': 6,
                              'surprise': 4,
                              'trust': 1}},
      'Mustang': {'Everyone': {'anger': 2},
                  'Fuery': {'anger': 3, 'surprise': 1},
                  'Hawkeye': {'anger': 1,
                              'joy': 6,
                              'surprise': 1,
                              'trust': 1},
                  'Mustang': {'joy': 2, 'trust': 1},
                  'the team': {'anger': 1}}}

result = {key: dict(sum(map(Counter, inner.values()), Counter())) for key, inner in d1.items()}

print(result)

выход

{'Havoc': {'joy': 3, 'surprise': 2, 'anticipation': 4}, 'Mustang': {'joy': 8, 'trust': 2, 'anger': 7, 'surprise': 2}, 'Hawkeye': {'joy': 8, 'surprise': 4, 'anger': 1, 'trust': 2}, 'Breda': {'surprise': 1, 'anger': 1, 'anticipation': 3}, 'Fuery': {'fear': 4, 'surprise': 1, 'anticipation': 2}}

Оператор sum(map(Counter, inner.values()), Counter()) преобразует каждый внутренний словарь в счетчик, а затем объединяет их вместе, используя sum . Это может быть сделано, потому что Counter реализует сложение, например:

Counter({'anticipation': 2}) + Counter({'anticipation': 1, 'surprise': 1})

возвращается:

Counter({'anticipation': 3, 'surprise': 1})

UPDATE

Если вы хотите получить сумму для каждого ключа, просто добавьте следующие строки:

total = { key : sum(inner.values()) for key, inner in result.items() }
print(total)

выход

{'Hawkeye': 15, 'Mustang': 19, 'Fuery': 7, 'Havoc': 9, 'Breda': 5}
...