3

I have a dictionary containing string keys and int values that I want to be sorted. I want it to first be sorted by decreasing value number, then in alphabetical order.

For example if you had a dictionary containing:

my_dict = {'zebra':1, 'the':201, 'apple':1, 'chicken':58}

The resulting sorted list would contain:

{('the', 201), ('chicken', 58), ('apple', 1), ('zebra', 1)

Currently I'm using the following:

my_list = sorted(my_dict.items(), key=lambda x: (x[1],x[0])

I get a list sorted first in ascending value order and then in alphabetical.

How can I reverse the values but not the keys? I know you can pass a third parameter reverse=[boolean] to the sorted() method, but it either does or does not reverse BOTH keys and values. How can sort by just one reversal? Thanks for any help!

Will
  • 24,082
  • 14
  • 97
  • 108
keenns
  • 863
  • 4
  • 14
  • 26
  • not really duplicate but the "sort by value descending then by key ascending" has answers posted [on this question](http://stackoverflow.com/questions/37513551/how-to-sort-tuple-element-first-on-the-basis-of-key-and-then-on-the-basis-of-val) – Tadhg McDonald-Jensen Jun 05 '16 at 02:43

2 Answers2

6

Just negate the value and use it as primary key:

>>> my_dict = {'zebra':1, 'the':201, 'apple':1, 'chicken':58}
>>> sorted(my_dict.items(), key=lambda x: (-x[1], x[0]))
[('the', 201), ('chicken', 58), ('apple', 1), ('zebra', 1)]
niemmi
  • 17,113
  • 7
  • 35
  • 42
0

As sorting is stable in Python, you can simply sort it twice: first by the secondary key, then by the primary key:

In [29]: from operator import itemgetter
In [30]: my_dict = {'zebra':1, 'the':201, 'apple':1, 'chicken':58}
In [31]: my_list = sorted(sorted(my_dict.iteritems(), key=itemgetter(0)), key=itemgetter(1), reverse=True)

In [32]: my_list
Out[32]: [('the', 201), ('chicken', 58), ('apple', 1), ('zebra', 1)]

This documentation explains stable sorting in Python in more detail.

Will
  • 24,082
  • 14
  • 97
  • 108