문제

I have dictionary with three-level nesting, eg:

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

All 2nd-level dictionaries contain the same elements, so I want to change it to

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

i.e. essentially switch nesting order. But when I write code like

d2 = {}
d2['a1']['c1']['sp1'] = 2

It just throws KeyError with whatever values happens to be 'a1'. How do I perform such operation?

도움이 되었습니까?

해결책 2

To do this, you can use defaultdict, which allows you to define a default initialization action on a dict.

In your case, you want a reverse-order recursive defaultdict, with a classmethod reverse_recursive_make() which unrolls and reverses the key order:

  • when passed in a key-value pair or None, returns a (toplevel) dict
  • when passed in a dict, recurses into each of the {k:v} pairs

I'm not going to write the code for that because what you want can be much more easily achieved with SQL, like I commented.

FOOTNOTE: your version with lambdas (comment below) is perfect.

(If you insist on using dicts, and not some other data structure)

다른 팁

If you are doing it manually like the snippet you tried, this is how you should be doing it:

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

But it is unclear as to why you are doing it. As OmnipotentEntity suggested in the comments, may be you need to use a different data structure to store the data.

something like this should work

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

I may have my indexing off a little, but that should be about right.

라이센스 : CC-BY-SA ~와 함께 속성
제휴하지 않습니다 StackOverflow
scroll top