3

I have a JSON list looks like this:

[{ "id": "1", "score": "100" },
{ "id": "3", "score": "89" },
{ "id": "1", "score": "99" },
{ "id": "2", "score": "100" },
{ "id": "2", "score": "59" }, 
{ "id": "3", "score": "22" }]

I want to sort the id first, I used

sorted_list = sorted(json_list, key=lambda k: int(k['id']), reverse = False)

This will only sort the list by id, but base on id, I also want sort the score as will, the final list I want is like this:

[{ "id": "1", "score": "100" },
{ "id": "1", "score": "99" },
{ "id": "2", "score": "100" },
{ "id": "2", "score": "59" },
{ "id": "3", "score": "89" }, 
{ "id": "3", "score": "22" }]

So for each id, sort their score as well. Any idea how to do that?

1 Answer 1

6

use a tuple adding second sort key -int(k["score"]) to reverse the order when breaking ties and remove reverse=True:

sorted_list = sorted(json_list, key=lambda k: (int(k['id']),-int(k["score"])))

[{'score': '100', 'id': '1'}, 
 {'score': '99', 'id': '1'}, 
 {'score': '100', 'id': '2'}, 
 {'score': '59', 'id': '2'},
 {'score': '89', 'id': '3'}, 
 {'score': '22', 'id': '3'}]

So we primarily sort by id from lowest-highest but we break ties using score from highest-lowest. dicts are also unordered so there is no way to put id before score when you print without maybe using an OrderedDict.

Or use pprint:

from pprint import pprint as pp

pp(sorted_list)

[{'id': '1', 'score': '100'},
 {'id': '1', 'score': '99'},
 {'id': '2', 'score': '100'},
 {'id': '2', 'score': '59'},
 {'id': '3', 'score': '89'},
 {'id': '3', 'score': '22'}]
Sign up to request clarification or add additional context in comments.

3 Comments

@MalikBrahimi, i don't think you will get the correct output though, the OP wants to sort from lowest to highest id but break ties with highest to lowest score
@MalikBrahimi, i should be x but it still wont work, you cannot sort string digits without casting to int and in this case the OP wants to sort both ways so it is not a straightforward sort
Good answer. You could print out the id before the score without using OrderedDict with something like '{{ "id": "{id}", "score": "{score}" }}'.format(**dct) for each dictionary in the sorted list.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.