I have a list of dictionary which I am sorting using multiple keys.
Now I want to push all the elements that have zero rank (rank is a key)
basically rank 0 must be at bottom
mylist = [
{
"score": 5.0,
"rank": 2,
"duration": 123,
"amount": "18.000",
},
{
"score": -1.0,
"rank": 0,
"duration": 23,
"amount": "-8.000",
},
{
"score": -2.0,
"rank": 0,
"duration": 63,
"amount": "28.000",
},
{
"score": 2.0,
"rank": 1,
"duration": 73,
"amount": "18.000",
},
]
from operator import itemgetter
sort_fields = ['rank', 'duration']
sorted_list = sorted(mylist, key=itemgetter(*sort_fields), reverse=False)
print(sorted_list)
current output
[{'score': -1.0, 'rank': 0, 'duration': 23, 'amount': '-8.000'}, {'score': -2.0, 'rank': 0, 'duration': 63, 'amount': '28.000'}, {'score': 2.0, 'rank': 1, 'duration': 73, 'amount': '18.000'}, {'score': 5.0, 'rank': 2, 'duration': 123, 'amount': '18.000'}]
expected output
[{'score': 2.0, 'rank': 1, 'duration': 73, 'amount': '18.000'}, {'score': 5.0, 'rank': 2, 'duration': 123, 'amount': '18.000'},{'score': -1.0, 'rank': 0, 'duration': 23, 'amount': '-8.000'}, {'score': -2.0, 'rank': 0, 'duration': 63, 'amount': '28.000'}, ]
CodePudding user response:
mylist = [
{
"score": 5.0,
"rank": 2,
"duration": 123,
"amount": "18.000",
},
{
"score": -1.0,
"rank": 0,
"duration": 23,
"amount": "-8.000",
},
{
"score": -2.0,
"rank": 0,
"duration": 63,
"amount": "28.000",
},
{
"score": 2.0,
"rank": 1,
"duration": 73,
"amount": "18.000",
},
]
sorted_list = sorted(mylist, key = lambda x: (x['rank'] if x['rank'] > 0 else float('inf'),x['duration']))
print(sorted_list)
CodePudding user response:
You should make the key function return a tuple of values based on the precedence of the sorting criteria. Since the first of your sorting criteria is in fact whether the rank is zero, make that test the first item of the tuple. Then you got the rest, namely the rank and the duration, correctly in order:
sorted_list = sorted(mylist, key=lambda d: (d['rank'] == 0, d['rank'], d['duration'])))