Сортировать вложенный словарь по нескольким ключам - PullRequest
0 голосов
/ 11 мая 2018

Я хочу, чтобы все значения словаря были в порядке возрастания.

Мой словарь, df, выглядит следующим образом:

df = {("A",): {"a": {"a1": 0.5, "a2": 0.2, "a3":1.0}},
      ("B",): {"b1": 0.8, "b2": 0.4}}

Мой идеальный вывод будет:

A⇨
 a→a2:0.2
B⇨
 b2→0.4
A⇨
 a→a1:0.5
  ・
  ・
  ・

Я написал это:

for key,value in sorted(df.items(), key=lambda x:x[0]):
    print(key)
    print(value)

Но когда я запускаю его, словарь сортируется в алфавитном порядке .. Перезапись как key=lambda x:x[1] поднимает KeyError.

Как я могу это сделать?

Ответы [ 2 ]

0 голосов
/ 11 мая 2018

Сначала я сглажу dict, а затем отсортирую. Что-то вроде:

def flatten_dict(d_in, d_out, parent_key):
    for k, v in d_in.items():
        if isinstance(v, dict):
            flatten_dict(v, d_out, parent_key + (k,))
        else:
            d_out[parent_key + (k,)] = v


df = {("A",): {"a": {"a1": 0.5, "a2": 0.2, "a3":1.0}},
    ("B",): {"b1": 0.8, "b2": 0.4}}

d_out = {}

flatten_dict(df, d_out, tuple())

print(d_out)

for key, value in sorted(d_out.items(), key=lambda x: x[1]):
    print(key)
    print(value)

Таким образом, вы все равно можете использовать его для поиска значений по их сплющенной клавише.

0 голосов
/ 11 мая 2018

Одним из решений является использование рекурсивной функции для преобразования словаря в список кортежей, например:

 (('A',), 'a', 'a1', 0.5), (('A',), 'a', 'a2', 0.2), (('A',), 'a', 'a3', 1.0), ...

, а затем сортировка этого списка кортежей:

def dict_to_list(input_dict):
    for key, value in input_dict.items():
        if isinstance(value, dict):
            for nested_value in dict_to_list(value):
                yield (key, ) + nested_value
        else:
            yield (key, value)

print(sorted(dict_to_list(df), key=lambda value: value[-1]))


>>> [(('A',), 'a', 'a2', 0.2), (('B',), 'b2', 0.4), (('A',), 'a', 'a1', 0.5), (('B',), 'b1', 0.8), (('A',), 'a', 'a3', 1.0)]
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...