改变三层嵌套Python字典的顺序

1 投票
3 回答
1522 浏览
提问于 2025-04-18 02:46

我有一个字典,里面有三层嵌套,比如:

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

像这样应该可以工作

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

我可能在索引上有点小问题,但大致上应该是对的。

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在评论中提到的,可能你需要用另一种数据结构来存储这些数据。

0

要做到这一点,你可以使用defaultdict,它允许你在字典中定义一个默认的初始化操作。

在你的情况下,你想要一个反向递归的defaultdict,并且需要一个类方法reverse_recursive_make(),这个方法可以展开并反转键的顺序:

  • 当传入一个键值对或None时,返回一个(顶层)字典
  • 当传入一个字典时,递归处理每一个{k:v}对

我不打算为这个写代码,因为你想要的功能用SQL来实现会简单得多,就像我在评论中提到的那样。

脚注:你用lambda写的版本(下面的评论)非常完美。

(如果你坚持使用字典,而不是其他数据结构)

撰写回答