Sorting a dictionary by value then by key
Question:
This seems like it has to be a dupe but my SO-searching-fu is poor today…
Say I have a dictionary of integer key/values, how can I sort the dictionary by the values descending, then by the key descending (for common values).
Input:
{12:2, 9:1, 14:2}
{100:1, 90:4, 99:3, 92:1, 101:1}
Output:
[(14,2), (12,2), (9,1)] # output from print
[(90,4), (99,3), (101,1), (100,1), (92,1)]
Answers:
In [62]: y={100:1, 90:4, 99:3, 92:1, 101:1}
In [63]: sorted(y.items(), key=lambda x: (x[1],x[0]), reverse=True)
Out[63]: [(90, 4), (99, 3), (101, 1), (100, 1), (92, 1)]
The key=lambda x: (x[1],x[0])
tells sorted
that for each item x
in y.items()
, use (x[1],x[0])
as the proxy value to be sorted. Since x
is of the form (key,value)
, (x[1],x[0])
yields (value,key)
. This causes sorted
to sort by value
first, then by key
for tie-breakers.
reverse=True
tells sorted
to present the result in descending, rather than ascending order.
See this wiki page for a great tutorial on sorting in Python.
PS. I tried using key=reversed
instead, but reversed(x)
returns an iterator, which does not compare as needed here.
Try this:
>>> d={100:1, 90:4, 99:3, 92:1, 101:1}
>>> sorted(d.items(), lambda a,b:b[1]-a[1] or a[0]-b[0])
Maybe this is more explicit:
>>> y = {100:1, 90:4, 99:3, 92:1, 101:1}
>>> reverse_comparison = lambda (a1, a2), (b1, b2):cmp((b2, b1), (a2, a1))
>>> sorted(y.items(), cmp=reverse_comparison)
[(90, 4), (99, 3), (101, 1), (100, 1), (92, 1)]
This seems like it has to be a dupe but my SO-searching-fu is poor today…
Say I have a dictionary of integer key/values, how can I sort the dictionary by the values descending, then by the key descending (for common values).
Input:
{12:2, 9:1, 14:2}
{100:1, 90:4, 99:3, 92:1, 101:1}
Output:
[(14,2), (12,2), (9,1)] # output from print
[(90,4), (99,3), (101,1), (100,1), (92,1)]
In [62]: y={100:1, 90:4, 99:3, 92:1, 101:1}
In [63]: sorted(y.items(), key=lambda x: (x[1],x[0]), reverse=True)
Out[63]: [(90, 4), (99, 3), (101, 1), (100, 1), (92, 1)]
The key=lambda x: (x[1],x[0])
tells sorted
that for each item x
in y.items()
, use (x[1],x[0])
as the proxy value to be sorted. Since x
is of the form (key,value)
, (x[1],x[0])
yields (value,key)
. This causes sorted
to sort by value
first, then by key
for tie-breakers.
reverse=True
tells sorted
to present the result in descending, rather than ascending order.
See this wiki page for a great tutorial on sorting in Python.
PS. I tried using key=reversed
instead, but reversed(x)
returns an iterator, which does not compare as needed here.
Try this:
>>> d={100:1, 90:4, 99:3, 92:1, 101:1}
>>> sorted(d.items(), lambda a,b:b[1]-a[1] or a[0]-b[0])
Maybe this is more explicit:
>>> y = {100:1, 90:4, 99:3, 92:1, 101:1}
>>> reverse_comparison = lambda (a1, a2), (b1, b2):cmp((b2, b1), (a2, a1))
>>> sorted(y.items(), cmp=reverse_comparison)
[(90, 4), (99, 3), (101, 1), (100, 1), (92, 1)]