改变三层嵌套Python字典的顺序
我有一个字典,里面有三层嵌套,比如:
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写的版本(下面的评论)非常完美。
(如果你坚持使用字典,而不是其他数据结构)