If I have a list that contains a list that looks like this
['a',1] ['a',2] ['a',3] ['b',1] ['b',2] ['b',3]
How can I sort them so that element 0 is sorted descending and element 1 sorted ascending so the result would look like
['b',1] ['b',2] ['b',3] ['a',1] ['a',2] ['a',3]
Using itemgetter I can pass in reverse on element 0 but I then resort against element to of course it ruins the previous sort. I can’t do a combined key since it needs to first sort descending and then ascending.
Answers:
Thank you for visiting the Q&A section on Magenaut. Please note that all the answers may not help you solve the issue immediately. So please treat them as advisements. If you found the post helpful (or not), leave a comment & I’ll get back to you as soon as possible.
Method 1
L = [['a',1], ['a',2], ['a',3], ['b',1], ['b',2], ['b',3]] L.sort(key=lambda k: (k[0], -k[1]), reverse=True)
L now contains:
[['b', 1], ['b', 2], ['b', 3], ['a', 1], ['a', 2], ['a', 3]]
Method 2
You can do successive rounds of sorting as python’s sort is stable. You need to first sort on the secondary key though. See also the official HOW TO.
from operator import itemgetter l = [['a',2], ['a',1], ['b', 2], ['a',3], ['b',1], ['b',3]] l.sort(key=itemgetter(1)) l.sort(key=itemgetter(0), reverse=True) # [['b', 1], ['b', 2], ['b', 3], ['a', 1], ['a', 2], ['a', 3]]
Method 3
Something like
def mycmp(a, b):
res = cmp(a[0], b[0])
if res == 0:
return cmp(a[1], b[1])
return res
newlist = sorted(input_list, cmp=mycmp)
The comparison method first checks the first item of each element. If they are equal it will check the second items of each element. The return value inside the mycmp() implementation may be negated in order to implemented a different sorting behavior.
All methods was sourced from stackoverflow.com or stackexchange.com, is licensed under cc by-sa 2.5, cc by-sa 3.0 and cc by-sa 4.0