Sorting Tuples In Python Using Different Orders For Different Fields
Solution 1:
If the values are numeric, you can do this easily using lambda
:
sorted(student_tuples, key=lambda x: (x[2],x[4],-x[0],x[1]))
#^ This field will be # in descending order
If you can't easily negate the order inside a lambda function, you need to rely on the stableness of python sorting and sort a few times:
s = sorted(student_tuples, key=itemgetter(1))
s.sort(key=itemgetter(0),reversed=True)
s.sort(key=itemgetter(2,4))
I explain it in more depth in this answer.
Proof that my answers above accomplish the same thing (with numeric input):
import random
defrand_tuple():
""" Return a random 5-tuple """returntuple( random.random() for _ inrange(5) )
#100 random 5-tuples
lst = [ rand_tuple() for _ inrange(100) ]
#sort the list using method 1
sorted_lst = sorted(lst, key = lambda x: (x[2],x[4],-x[0],x[1]))
#sort the list in place using method 2
lst.sort(key = itemgetter(1)) #<- Rightmost tuple element first!!!
lst.sort(key = itemgetter(0), reversed = True)
lst.sort(key = itemgetter(2,4))
print (lst == sorted_lst) #True -- Results are the same :-)
Solution 2:
You could create a class with meaningful attribute names instead of just numeric indices; that would sort easily if you give it __cmp__
(python 2.x) or __eq__
and __lt__
plus @total_ordering (python 3.x).
Another option would be to keep the tuples, convert them to lists, and negate any numeric fields that you need to sort in reverse. You can kind of do this for strings, but it's not as neat as for numbers.
Part of the reason tuples sort fast, is that they aren't super flexible.
Post a Comment for "Sorting Tuples In Python Using Different Orders For Different Fields"