Skip to content Skip to sidebar Skip to footer

Sorting Tuples In Python Using Different Orders For Different Fields

Assume we have a list of 5 tuple: (a, b , c, d, e) Let the list be student_tuples. I wish to sort the list different orders for different fields. The below mentioned command sor

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"