Sort dictionary in Python by items inside list

Question:

Is it possible to sort this kind of dictionaries:

  1. First by rank
  2. If rank is the same then sort by first element in other_ranks list
  3. If first element in other_ranks is the same – go deeper until last element in list.

If this is a trouble, I can make this dictionary structurized in different way.

{'rank': 6, 'other_ranks': [7, 5]}
{'rank': 1, 'other_ranks': [7, 11, 6, 2]}
{'rank': 0, 'other_ranks': [12]}
{'rank': 1, 'other_ranks': [13, 11, 4, 3]}
{'rank': 1, 'other_ranks': [14, 12, 6, 5]}
{'rank': 4, 'other_ranks': [5, 4, 3, 2]}
{'rank': 0, 'other_ranks': [12]}
Asked By: pablos91

||

Answers:

Assuming a list, you can use operator.itemgetter in conjunction with the key argument of sorted:

from operator import itemgetter

lst = [{'rank': 6, 'other_ranks': [7, 5]},
       {'rank': 1, 'other_ranks': [7, 11, 6, 2]},
       {'rank': 0, 'other_ranks': [12]},
       {'rank': 1, 'other_ranks': [13, 11, 4, 3]},
       {'rank': 1, 'other_ranks': [14, 12, 6, 5]},
       {'rank': 4, 'other_ranks': [5, 4, 3, 2]},
       {'rank': 0, 'other_ranks': [12]}]


res = sorted(lst, key=itemgetter("rank", "other_ranks"))
print(res)

Output

[{'other_ranks': [12], 'rank': 0},
 {'other_ranks': [12], 'rank': 0},
 {'other_ranks': [7, 11, 6, 2], 'rank': 1},
 {'other_ranks': [13, 11, 4, 3], 'rank': 1},
 {'other_ranks': [14, 12, 6, 5], 'rank': 1},
 {'other_ranks': [5, 4, 3, 2], 'rank': 4},
 {'other_ranks': [7, 5], 'rank': 6}]

The key here is that list and tuples are compared lexicographically, from the documentation:

Sequences of the same type also support comparisons. In particular,
tuples and lists are compared lexicographically by comparing
corresponding elements.

Therefore just compare them as is.

Answered By: Dani Mesejo

That’s called lexigraphical comparison. Python’s tuples implement that.

dictionaries = [
    {'rank': 6, 'other_ranks': [7, 5]},
    {'rank': 1, 'other_ranks': [7, 11, 6, 2]},
    {'rank': 0, 'other_ranks': [12]},
    {'rank': 1, 'other_ranks': [13, 11, 4, 3]},
    {'rank': 1, 'other_ranks': [14, 12, 6, 5]},
    {'rank': 4, 'other_ranks': [5, 4, 3, 2]},
    {'rank': 0, 'other_ranks': [12]},
]
dictionaries.sort(key=lambda dict_: (dict_['rank'], ) + tuple(dict_['other_ranks']))
Answered By: Homer512
Categories: questions Tags: ,
Answers are sorted by their score. The answer accepted by the question owner as the best is marked with
at the top-right corner.