How to sort a dictionary by value (DESC) then by key (ASC)?

Posted on

Question :

How to sort a dictionary by value (DESC) then by key (ASC)?

Just after discovering the amazing sorted(), I became stuck again.

The problem is I have a dictionary of the form string(key) : integer(value) and I need to sort it in descending order of its integer values, but if two elements where to have same value, then by ascending order of key.

An example to make it clearer:

d = {'banana':3, 'orange':5, 'apple':5}
out: [('apple', 5), ('orange', 5), ('banana', 3)]

After doing some research I arrived at something like:

sorted(d.items(), key=operator.itemgetter(1,0), reverse=True)
out: [('orange', 5), ('apple', 5), ('banana', 3)]

This is because it’s reverse-sorting both the value and the key. I need the key to be un-reversed.

Asked By: ecr


Answer #1:

Something like

In [1]: d = {'banana': 3, 'orange': 5, 'apple': 5}

In [2]: sorted(d.items(), key=lambda x: (-x[1], x[0]))
Out[2]: [('apple', 5), ('orange', 5), ('banana', 3)]
Answered By: Lev Levitsky

Answer #2:

  • Dictionaries can’t be sorted directly, so you need to instead sort the items(), the list of tuples containing key/value pairs.

  • Since you want to sort by the value field, then the key fields, it is necessary to extract those field from the tuple for use as the sort key using operator.itemgetter which gets the specified field.

  • Lastly, to sort descending on one field and descending on another, do two passes, first sorting by the secondary key ascending, and then another pass sorting by the primary key descending. This step relies on Python’s sort stability.

For example:

import operator
In [1]: d = {'banana': 3, 'orange': 5, 'apple': 5}

In [2]: fruit = sorted(d.items(), key=operator.itemgetter(0))
In [3]: sorted(fruit, key=operator.itemgetter(1), reverse=True)
Out[3]: [('apple', 5), ('orange', 5), ('banana', 3)]

See the Python Sorting-HOWTO guide for more details.

Answered By: Sergey Zakharov

Leave a Reply

Your email address will not be published. Required fields are marked *