#python
#python #словарь #вложенный
Вопрос:
Если у меня есть следующий словарь:
dict_a = {'a': {'x': 0, 'y': 1, 'z': 2},
'b': {'x': 3, 'y': 4, 'z': 5}}
Каков наилучший способ переключить структуру словаря на:
dict_b = {'x': {'a': 0, 'b': 3},
'y': {'a': 1, 'b': 4},
'z': {'a': 2, 'b': 5}}
Комментарии:
1. Лучше уточнить, нужно ли вам обрабатывать несоответствующие данные.
2. Всегда ли словарь имеет глубину в два уровня ?
3. Да, всегда два уровня
Ответ №1:
Со словарем по умолчанию
Учитывая, что словарь всегда имеет глубину в два уровня, вы можете сделать это с помощью 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
Что дает:
>>> 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
является подклассом dict
, вы можете снова превратить результат в ванильный dict
с dict_b = dict(dict_b)
помощью (как показано во втором запросе).
С pandas
Вы также можете использовать pandas
для этого:
from pandas import DataFrame
dict_b = DataFrame(dict_a).transpose().to_dict()
Это дает:
>>> DataFrame(dict_a).transpose().to_dict()
{'y': {'a': 1, 'b': 4}, 'x': {'a': 0, 'b': 3}, 'z': {'a': 2, 'b': 5}}
Ответ №2:
Нам не нужно defaultdict
переносить вложенный dict, если мы используем 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