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

X = {"X1":["O","E","P"],"X2":["M"]}
Y = {"O":["a"],"E":["b","c"],"P":["d"],"M":["r"]}
Z = {"a":["1"],"b":["2","3"],"c":[],"d":["4","5"],"r":["6"]}

d1 = {}
for k in X:
    A = X[k]
    d2 = {}
    for v in A:
        B = Y[v]
        d3 = {}
        for i in B:
            C = Z[i]
            d3.update({i:C})
        d2.update({v:d3})
    d1.update({k:d2})
1
Kevin_ALA 27 Июн 2019 в 06:35

2 ответа

Лучший ответ

Вы можете использовать простую рекурсию:

X = {"X1":["O","E","P"],"X2":["M"]}
Y = {"O":["a"],"E":["b","c"],"P":["d"],"M":["r"]}
Z = {"a":["1"],"b":["2","3"],"c":[],"d":["4","5"],"r":["6"]}
start = [X, Y, Z]
def group(d):
   return d if all(all(c not in i for i in start) for c in d) else \
           {i:group([c[i] for c in start if i in c][0]) for i in d}

r = {a:group(b) for a, b in X.items()}
print(r == d1) #d1 generated from OP's solution

Выход:

{'X1': {'O': {'a': ['1']}, 'E': {'b': ['2', '3'], 'c': []}, 'P': {'d': ['4', '5']}}, 'X2': {'M': {'r': ['6']}}}
True
4
Ajax1234 27 Июн 2019 в 03:42

Словарное понимание для 1 строки, в основном та же процедура, что и для вашего вложенного цикла for:

{k: {v0:{v1: Z[v1] for v1 in Y[v0]} for v0 in v} for k, v in X.items()}

Выходы:

{'X1': {'O': {'a': ['1']},
  'E': {'b': ['2', '3'], 'c': []},
  'P': {'d': ['4', '5']}},
 'X2': {'M': {'r': ['6']}}}

Объяснение : Алгоритм OP просматривает список значений в следующем словаре, используя в качестве ключей каждое из значений в текущем списке, пока не будет достигнут последний словарь. В псевдокоде вложенность выглядит следующим образом:

# pseudo code
for key, values in X
    for valX in values:
        for valY in Y[valX]: # note Y[valX] is a list
            Z[valY]

Переводя это в понимание, мы начинаем с самого внутреннего цикла, выходим и добавляем необходимые украшения

Шаг 1:

{y:Z[y] for ys in Y.values() for y in ys}
# out: 
{'a': ['1'], 'b': ['2', '3'], 'c': [], 'd': ['4', '5'], 'r': ['6']}

Шаг 2: теперь мы ищем ys напрямую

{x:{y:Z[y] for y in Y[x]} for xs in X.values() for x in xs}
# out:
{'O': {'a': ['1']},
 'E': {'b': ['2', '3'], 'c': []},
 'P': {'d': ['4', '5']},
 'M': {'r': ['6']}}

Шаг 3: теперь мы вставляем ключи из X и добавляем еще один уровень вложенности словарей

{k:{x:{y:Z[y] for y in Y[x]} for x in xs} for k, xs in X.items()}

Что дает желаемый результат

В общем, при попытке преобразовать вложенные циклы в понимание, начните с самого внутреннего цикла и работайте вовне.

4
Haleemur Ali 27 Июн 2019 в 04:43