23

I have the dictionary {'Bill': 4, 'Alex' : 4, 'Bob' : 3, "Charles": 7}

I need to sort this dictionary first numerically, then within that, alphabetically. If 2 items have the same number key, they need to be sorted alphabetically.

The output of this should be Bob, Alex, Bill, Charles

I tried using lambda, list comprehension, etc but I can't seem to get them to sort correctly.

Bhargav Rao
  • 50,140
  • 28
  • 121
  • 140
Infiniti
  • 339
  • 1
  • 2
  • 7

2 Answers2

43

Using sorted with key function (order by value (d[k]) first, then key k):

>>> d = {'Bill': 4, 'Alex' : 4, 'Bob' : 3, "Charles": 7}    
>>> sorted(d, key=lambda k: (d[k], k))
['Bob', 'Alex', 'Bill', 'Charles']
falsetru
  • 357,413
  • 63
  • 732
  • 636
  • 2
    How would I do one value descending and the other ascending? – Alex Stewart Sep 26 '18 at 09:02
  • 7
    @AlexStewart, For numerical value, you can control that with negation (`-`) for descending. For non-numerical value, you should define subclass with `__lt__` defined. – falsetru Sep 26 '18 at 13:01
  • @AlexStewart, You can also think of the reverse. Keep the continuous value positive and then put reverse=True into the sorted method. `sorted(d, key=lambda k: (k[1], k[0]), reverse=True)` – Kemal Toprak Uçar Oct 19 '22 at 12:24
10

Sort on the dictionary's items (which are tuples) using sorted(). You can specify the sort key which will be by the dictionary's values, and then its keys:

>>> d = {'Bill': 4, 'Alex' : 4, 'Bob' : 3, "Charles": 7}
>>> sorted(d.items(), key=lambda x:(x[1],x[0]))
[('Bob', 3), ('Alex', 4), ('Bill', 4), ('Charles', 7)]
>>> [t[0] for t in sorted(d.items(), key=lambda x:(x[1],x[0]))]
['Bob', 'Alex', 'Bill', 'Charles']
mhawke
  • 84,695
  • 9
  • 117
  • 138