【问题标题】:How to combine dictionaries into a nested dictionary?如何将字典组合成嵌套字典?
【发布时间】:2019-06-27 03:35:33
【问题描述】:

我想将我的 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})

【问题讨论】:

  • 请注意,您可以使用dict[key] = value 而不是dict.update({key: value}) 来简化,并消除只使用一次的名称(即ABC)。所以C = Z[i]; d3.update({i: C}) 会变成d3[i] = Z[i]

标签: python dictionary


【解决方案1】:

你可以使用简单的递归:

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

【讨论】:

  • 非常感谢。你有学习递归的有用资源吗?
  • @Kevin_ALA 看看这个link。它有几个例子很好地介绍和解释了递归。另请参阅here,其中包含有用的示例代码。
【解决方案2】:

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

产生期望的结果

一般来说,当尝试将嵌套循环转换为推导式时,从最内层循环开始,然后向外工作。

【讨论】:

  • +1 我想出了基本相同的东西:{k: {i: {j: Z[j] for j in Y[i]} for i in X[k]} for k in X}
  • 对其工作原理的简短说明可能会有所帮助:)
  • @l'L'l,添加了关于解决方案构造的说明
猜你喜欢
  • 2020-07-29
  • 2019-04-06
  • 1970-01-01
  • 2019-01-09
  • 2022-01-15
  • 1970-01-01
  • 1970-01-01
  • 2021-08-09
  • 1970-01-01
相关资源
最近更新 更多