Создать вложенный словарь из словаря на основе повторяющихся значений - PullRequest
0 голосов
/ 04 июня 2018

Я новичок в Python (3.6) и пытаюсь найти способ создания вложенного словаря из списка списков.Пример ввода:

myList = [[1, B, C],[1, D, C],[1, E, C],[1, F, G],[1, H, G],[2, I, C],[2, J, C],[2, K, G]]

Что я хочу получить:

result = {1: {C: [B, D, E], G: [F, H]}, 2: {C: [I, J], G: [K]}}

На данный момент у меня есть:

result = defaultdict(list)
for key, *values in myList:
    result[key].extend(values)

Что даетмне вывод:

{1: [B, C, D, C, E, C, F, G, H, G], 2: [I, C, J, C, K, G]}

Я ищу способ создания вложенного словаря, где каждое повторяющееся значение в списке значений для ключа становится ключом под-словаря.Не могли бы вы посоветовать, какие подходы я могу рассмотреть, имея в виду, что я имею дело с большим набором данных?То, что я сделал до сих пор, имеет большой недостаток, поскольку я теряю информацию о том, какое значение должно быть присвоено, какой ключ в под-словарях.

Ответы [ 2 ]

0 голосов
/ 04 июня 2018

Вы можете использовать itertools.groupby с рекурсией для обработки ввода с подсписками произвольной длины:

import itertools
keys = [[lambda x:x[0], lambda x:x[1:]], [lambda x:x[-1], lambda x:x[:-1]]]
l = [[1, 'B', 'C'],[1, 'D', 'C'],[1, 'E', 'C'],[1, 'F', 'G'],[1, 'H', 'G'],[2, 'I', 'C'],[2, 'J', 'C'],[2, 'K', 'G']]
def group_result(d, keys):
  k, splice = keys[0]
  c = {a:[splice(i) for i in b] for a, b in itertools.groupby(sorted(d, key=k), key=k)}
  return {a:group_result(b, keys[1:]) if keys[1:] else [i for c in b for i in c] for a, b in c.items()}

print(group_result(l, keys))

Вывод:

{1: {'C': ['B', 'D', 'E'], 'G': ['F', 'H']}, 2: {'C': ['I', 'J'], 'G': ['K']}}
0 голосов
/ 04 июня 2018

Вы можете использовать defaultdict здесь, но просто передать list не будет работать, потому что вы не хотите, чтобы dict, значения которого являются списками;вам нужен дикт, значения которого являются диктатами, у каждого из которых есть значения, которые являются списками.Таким образом, вы должны передать второй слой defaultdict первому defaultdict.

from collections import defaultdict

seq = [[1, 'B', 'C'],[1, 'D', 'C'],[1, 'E', 'C'],[1, 'F', 'G'],[1, 'H', 'G'],[2, 'I', 'C'],[2, 'J', 'C'],[2, 'K', 'G']]
d = defaultdict(lambda: defaultdict(list))
for key1, value, key2 in seq:
    d[key1][key2].append(value)

print(d)

Результат:

defaultdict(<function <lambda> at 0x00DEC6A8>, {1: defaultdict(<class 'list'>, {'C': ['B', 'D', 'E'], 'G': ['F', 'H']}), 2: defaultdict(<class 'list'>, {'C': ['I', 'J'], 'G': ['K']})})

... Что эквивалентно, item-мудро, до {1: {'C': ['B', 'D', 'E'], 'G': ['F', 'H']}, 2: {'C': ['I', 'J'], 'G': ['K']}}

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...