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)]