Reputation: 333
I have a dict that contains data about different quarters (of years):
"data": {
"Q3/2016": 86,
"Q1/2016": 85,
"Q4/2016": 69,
"Q2/2016": 69,
"Q2/2017": 82,
"Q1/2017": 66,
},
How can I sort this so it looks like this
"data": {
"Q1/2016": 85,
"Q2/2016": 69,
"Q3/2016": 86,
"Q4/2016": 69,
"Q1/2017": 66,
"Q2/2017": 82,
},
Upvotes: 0
Views: 89
Reputation: 194
You should copy this dict into an ordered dict like
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)])
It seems to maintain the order while json serialisation too which is nice
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
}
Upvotes: 1
Reputation: 7519
Dictionaries cannot be ordered in-place since they have no order, but since Python 3.7 they remember insertion order so we can build an "ordered" dictionary by sorting key-value pairs from your unordered dictionary.
So the actual important part is the key
we pass as an argument to sorted
. In the following code, the key is a lambda function that takes each key, split it at /
and reverses the resulting tuple, so that keys are sorted first by year, then by quarter:
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)
output:
{'data': {
'Q1/2016': 85,
'Q2/2016': 69,
'Q3/2016': 86,
'Q4/2016': 69,
'Q1/2017': 66,
'Q2/2017': 82}
}
Upvotes: 2