Сортировка словаря по клавишам, состоящим из цифр и букв - PullRequest
0 голосов
/ 27 мая 2020

У меня есть словарь, содержащий данные о разных кварталах (годах):

"data": {
        "Q3/2016": 86,
        "Q1/2016": 85,
        "Q4/2016": 69,
        "Q2/2016": 69,
        "Q2/2017": 82,
        "Q1/2017": 66,
    },

Как мне отсортировать это так, чтобы оно выглядело так

"data": {
        "Q1/2016": 85,
        "Q2/2016": 69,
        "Q3/2016": 86,
        "Q4/2016": 69,
        "Q1/2017": 66,
        "Q2/2017": 82,
    },

Ответы [ 2 ]

2 голосов
/ 27 мая 2020

Словари не могут быть упорядочены на месте, поскольку в них нет порядка, но, начиная с Python 3.7, они запоминают порядок вставки, поэтому мы можем построить «упорядоченный» словарь, отсортировав пары ключ-значение из вашего неупорядоченного словаря.

Таким образом, наиболее важной частью является key, который мы передаем в качестве аргумента sorted. В следующем коде ключ представляет собой лямбда-функцию, которая берет каждый ключ, разделяет его на / и меняет полученный кортеж, так что ключи сортируются сначала по году, а затем по кварталу:

d = {"data": { 
    "Q3/2016": 86, 
    "Q1/2016": 85, 
    "Q4/2016": 69, 
    "Q2/2016": 69, 
    "Q2/2017": 82, 
    "Q1/2017": 66, 
    }
}
d['data'] = {k: v for k, v in sorted(d['data'].items(), key=lambda x: x[0].split('/')[::-1])}
print(d)

вывод:

{'data': {
     'Q1/2016': 85,
     'Q2/2016': 69,
     'Q3/2016': 86,
     'Q4/2016': 69,
     'Q1/2017': 66,
     'Q2/2017': 82}
}
1 голос
/ 27 мая 2020

Вы должны скопировать этот dict в заказанный dict как

In [22]: from collections import OrderedDict
In [23]: data = {
    ...:         "Q3/2016": 86,
    ...:         "Q1/2016": 85,
    ...:         "Q4/2016": 69,
    ...:         "Q2/2016": 69,
    ...:         "Q2/2017": 82,
    ...:         "Q1/2017": 66,
    ...:     }
In [40]: def sort_key(key_val):
    ...:     key, val = key_val
    ...:     key = key.split("/")
    ...:     return int(key[1]), key[0]
    ...:
# add a custom sort key
In [24]: data = OrderedDict(sorted(data.items(), key=sort_key))

In [25]: data
Out[25]:
OrderedDict([('Q1/2016', 85),
             ('Q2/2016', 69),
             ('Q3/2016', 86),
             ('Q4/2016', 69),
             ('Q1/2017', 66),
             ('Q2/2017', 82)])

Кажется, он поддерживает порядок, пока json сериализация тоже, что приятно

In [27]: print(json.dumps(data, indent=4))
{
    "Q1/2016": 85,
    "Q2/2016": 69,
    "Q3/2016": 86,
    "Q4/2016": 69,
    "Q1/2017": 66,
    "Q2/2017": 82
}

...