I am new to python. In Python, I want to sort list of dictionary items first based on 'year' key and later with key which is alphanumeric ie P1, P2, P3.
Code snippet is as follows:
[
{"P9": 0, "year": 2023},
{"P13": 0, "year": 2023},
{"P10": 0, "year": 2023},
{"P11": 121200, "year": 2022},
{"P12": 0, "year": 2023},
]
Which first sorted by year in acending order becomes:
[
{"P11": 121200, "year": 2022},
{"P9": 0, "year": 2023},
{"P13": 0, "year": 2023},
{"P10": 0, "year": 2023},
{"P12": 0, "year": 2023},
]
Again later sorted by period key ie, P1,P2,P3 etc becomes:
[
{"P11": 121200, "year": 2022},
{"P9": 0, "year": 2023},
{"P10": 0, "year": 2023},
{"P12": 0, "year": 2023},
{"P13": 0, "year": 2023},
]
Above is the expected output, Now I don't know how do I sort it like this
CodePudding user response:
The sort function do all you need
You can pass a key function (a callable) for identifying the correct order. In your case:
unordered = [{'P9': 0, 'year': 2023}, {'P13': 0, 'year': 2023}, {'P10': 0, 'year': 2023}, {'P11': 121200, 'year': 2022}, {'P12': 0, 'year': 2023}]
#by year
sorted(unordered, key=lambda x: x['year'])
# out
[{'P11': 121200, 'year': 2022},
{'P9': 0, 'year': 2023},
{'P13': 0, 'year': 2023},
{'P10': 0, 'year': 2023},
{'P12': 0, 'year': 2023}]
For the period, the solution is a little bit tricky, you must identify how to select the P** key. We don't know how these dictionaries are built but doing some assumptions maybe something like:
sorted(unordered, key=lambda x: [lbl for lbl in x if lbl.startswith('P')][0] )
but here there are lacks of information to be more precise
CodePudding user response:
You can use sorted function, and specify a key function with it. But as you want to use two separate data points as keys, you can use tuple to build a key.
Because when tuples are compared, it first compares the very first entity in it, and if the first one matches, then it goes to check the second entity.
Example:
>>> (1,3) > (1, 4)
False
>>> (1, 4) < (2,2)
True
>>> (1, 4, 1) < (2, 1)
True
So, here's how you can build your key function:
>>> unordered = [{'P9': 0, 'year': 2023}, {'P13': 0, 'year': 2023}, {'P10': 0, 'year': 2023}, {'P11': 121200, 'year': 2022}, {'P12': 0, 'year': 2023}]
>>> ordered = sorted(
unordered,
key=lambda d: (d['year'], next(int(k[1:]) for k in d.keys() if k.startswith('P')))
)
>>> ordered
[{'P11': 121200, 'year': 2022}, {'P9': 0, 'year': 2023}, {'P10': 0, 'year': 2023}, {'P12': 0, 'year': 2023}, {'P13': 0, 'year': 2023}]
Here, I'm just assuming that you'll always have a key in the dictionary that starts with P
, and the remaining part of it is an integer.
CodePudding user response:
For sorting first base years
then sorting base first key of each dict
you can catch number and convert to int
then sorting like below:
>>> sorted(lst_dct, key=lambda x: (x['year'], int(list(x.keys())[0][1:])))
[{'P11': 121200, 'year': 2022},
{'P9': 0, 'year': 2023},
{'P10': 0, 'year': 2023},
{'P12': 0, 'year': 2023},
{'P13': 0, 'year': 2023}]