如何将字典合并为嵌套字典?

时间:2019-06-27 03:35:33

标签: python dictionary

我想将3个字典合并为1个嵌套字典。我编写了以下代码,以使用3个嵌套的for循环来执行此操作。但是对同一件事有任何有效的方法或递归函数吗?

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})

2 个答案:

答案 0 :(得分:4)

您可以使用简单的递归:

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

答案 1 :(得分:4)

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()}

产生预期的结果

通常,当尝试将嵌套循环转换为理解时,请从最里面的循环开始,然后向外进行。