Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

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

I need to sort a dictionary by first, values with reverse=True, and for repeating values, sort by keys, reverse=False

So far, I have this

dict = [('B', 3), ('A', 2), ('A', 1), ('I', 1), ('J', 1)] sorted(dict.items(), key=lambda x: (x[1],x[1]), reverse=True) 

which returns...

[('B', 3), ('A', 2), ('J', 1), ('I', 1), ('A', 1)] 

but I need it to be:

[('B', 3), ('A', 2), ('A', 1), ('I', 1), ('J', 1)] 

as you can see, when values are equal, I can only sort the key in a decreasing fashion as specified... But how can I get them to sort in an increasing fashion?

like image 955
Nicolas Hung Avatar asked Jan 22 '13 19:01

Nicolas Hung


People also ask

How do you sort by second value in a list of tuples?

In python, if you want to sort a list of tuples by the second element then we have the function called sort() and by using lambda function as a key function. A custom comparator is a key function in sort().

How do you sort a tuple in reverse order?

Sort tuples Passing a tuple to sorted() returns a sorted list. To convert a list to a tuple, use tuple() . You can write in one line. If you want to sort in descending order, set the argument reverse to True .

How do you reverse the list of tuples?

In Python, you can reverse the items of lists ( list ) with using reverse() , reversed() , and slicing. If you want to reverse strings ( str ) and tuples ( tuple ), use reversed() or slice.

What does sort reverse true do?

sort(reverse=True) will sort it in reverse order. If the list is already sorted, it will sort it in reverse order (i.e. reverse it) - but will likely take longer than list.


2 Answers

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 itemgetter d.sort(key=itemgetter(0)) d.sort(key=itemgetter(1),reverse=True) 

which works because python's sorting is stable.

like image 148
mgilson Avatar answered Sep 18 '22 14:09

mgilson


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)] 
like image 35
NPE Avatar answered Sep 21 '22 14:09

NPE