问题
If I have the following dictionary:
dict_a = {'a': {'x': 0, 'y': 1, 'z': 2},
'b': {'x': 3, 'y': 4, 'z': 5}}
What is the best way to switch the structure of the dictionary to:
dict_b = {'x': {'a': 0, 'b': 3},
'y': {'a': 1, 'b': 4},
'z': {'a': 2, 'b': 5}}
回答1:
With default dictionary
Given the dictionary is always two levels deep, you can do this with a defaultdict
:
from collections import defaultdict
dict_b = defaultdict(dict)
for k,v in dict_a.items():
for k2,v2 in v.items():
dict_b[k2][k] = v2
Which gives:
>>> dict_b
defaultdict(<class 'dict'>, {'x': {'a': 0, 'b': 3}, 'z': {'a': 2, 'b': 5}, 'y': {'a': 1, 'b': 4}})
>>> dict(dict_b)
{'x': {'a': 0, 'b': 3}, 'z': {'a': 2, 'b': 5}, 'y': {'a': 1, 'b': 4}}
defaultdict
is a subclass of dict
, you can turn the result again in a vanilla dict
with dict_b = dict(dict_b)
(as is demonstrated in the second query).
With pandas
You can also use pandas
for this:
from pandas import DataFrame
dict_b = DataFrame(dict_a).transpose().to_dict()
This gives:
>>> DataFrame(dict_a).transpose().to_dict()
{'y': {'a': 1, 'b': 4}, 'x': {'a': 0, 'b': 3}, 'z': {'a': 2, 'b': 5}}
回答2:
We don't need defaultdict
to transpose the nested dict if we use setdefault:
def transpose(nested_dict):
result = dict()
for x, nested in nested_dict.items():
for a, val in nested.items():
result.setdefault(a, dict())[x] = val
return result
来源:https://stackoverflow.com/questions/43391661/how-to-switch-the-nesting-structure-of-a-dictionary-of-dictionaries-in-python