更改三重嵌套Python字典的嵌套顺序

时间:2014-04-15 04:08:58

标签: python dictionary nested recursive-datastructures

我有三级嵌套字典,例如:

d = {
    'sp1':{
        'a1':{'c1':2,'c2':3},
        'a2':{'c3':1,'c4':4}
        },
    'sp2':{
        'a1':{'c1':3,'c2':3},
        'a2':{'c3':2,'c4':0}
        }
    }

所有二级词典都包含相同的元素,因此我想将其更改为

d2 = {'a1':{'c1':{'sp1':2,'sp2':3}, 'c2':{'sp1':3,'sp2':3}}}

即。本质上是切换嵌套顺序。但是当我编写像

这样的代码时
d2 = {}
d2['a1']['c1']['sp1'] = 2

它只会抛出KeyError,其中任何值恰好是'a1'。我该如何进行这样的操作?

3 个答案:

答案 0 :(得分:1)

如果您手动执行此操作,就像您尝试的代码段一样,这就是您应该这样做的方式:

>>> d = {
...     'sp1':{
...         'a1':{'c1':2,'c2':3},
...         'a2':{'c3':1,'c4':4}
...         },
...     'sp2':{
...         'a1':{'c1':3,'c2':3},
...         'a2':{'c3':2,'c4':0}
...         }
...     }
>>>
>>> e = {}
>>> e['a1'] = {}
>>> e['a1']['c1'] = {}
>>> e['a1']['c1']['sp1'] = d['sp1']['a1']['c1']
>>> e['a1']['c2'] = {}
>>> e['a1']['c2']['sp1'] = d['sp1']['a1']['c2']
>>> e['a2'] = {}
>>> e['a2']['c1'] = {}
>>> e['a2']['c2'] = {}
>>> e['a1']['c1']['sp2'] = d['sp2']['a1']['c1']
>>> e['a1']['c2']['sp2'] = d['sp2']['a1']['c2']
>>> e
{'a1': {'c2': {'sp1': 3, 'sp2': 3}, 'c1': {'sp1': 2, 'sp2': 3}}}
>>>

但目前还不清楚你为什么要这样做。正如OmnipotentEntity在评论中所建议的那样,您可能需要使用不同的数据结构来存储数据。

答案 1 :(得分:0)

为此,您可以使用defaultdict,它允许您在字典上定义默认初始化操作。

在您的情况下,您需要一个带有classmethod的逆序递归defaultdict reverse_recursive_make() ,展开并撤销按键顺序:

  • 传入键值对或None时,返回(顶级)词典
  • 在dict中传递时,会递归到每个{k:v}对

我不会为此编写代码,因为使用SQL可以更轻松地实现所需的代码,就像我评论的那样。

脚注:你的lambdas版本(下面的评论)是完美的。

(如果你坚持使用dicts,而不是其他一些数据结构)

答案 2 :(得分:0)

这样的事情应该起作用

d_final = {}
for k in d.keys():
    d2 = d[k]
    for k2 in d2.keys():
        d3 = d2[k2]
        for k3 in d3.keys():
            d4 = d_final.get(k2,{})
            d4[k] = d3[k3]
            d_final[k2] = d4

我可能会将索引关闭一点,但那应该是正确的。