Sort a list of tuples by second value, reverse=True and then by key, reverse=False Sort a list of tuples by second value, reverse=True and then by key, reverse=False python python

Sort a list of tuples by second value, reverse=True and then by key, reverse=False


The following works with your input:

d = [('B', 3), ('A', 2), ('A', 1), ('I', 1), ('J', 1)]sorted(d,key=lambda x:(-x[1],x[0]))

Since your "values" are numeric, you can easily reverse the sort order by changing the sign.

In other words, this sort puts things in order by value (-x[1]) (the negative sign puts big numbers first) and then for numbers which are the same, it orders according to key (x[0]).

If your values can't so easily be "negated" to put big items first, an easy work-around is to sort twice:

from operator import itemgetterd.sort(key=itemgetter(0))d.sort(key=itemgetter(1),reverse=True)

which works because python's sorting is stable.


In [4]: l = [('B', 3), ('A', 2), ('A', 1), ('I', 1), ('J', 1)]In [5]: sorted(l, key=lambda (x,y):(-y,x))Out[5]: [('B', 3), ('A', 2), ('A', 1), ('I', 1), ('J', 1)]


you can use collections.defaultdict:

In [48]: from collections import defaultdictIn [49]: dic=[('B', 3), ('A', 2), ('A', 1), ('I', 1), ('J', 1)]In [50]: d=defaultdict(list)In [51]: for x,y in dic:    d[y].append(x)    d[y].sort()          #sort the list

now d is something like:

 defaultdict(<type 'list'>, {1: ['A', 'I', 'J'], 2: ['A'], 3: ['B']}

i.e. A new dict with 1,2,3... as keys and corresponding alphabets stored in lists as values.

Now you can iterate over the sorted(d.items) and get the desired result using itertools.chain() and itertools.product().

In [65]: l=[ product(y,[x]) for x,y in sorted(d.items(),reverse=True)]In [66]: list(chain(*l))Out[66]: [('B', 3), ('A', 2), ('A', 1), ('I', 1), ('J', 1)]