hola
hola

Reputation: 950

Breaking ties in Python sort

I have a list of tuples, each tuple contains two integers. I need to sort the the list (in reverse order) according to the difference of the integers in each tuple, but break ties with the larger first integer.

Example

For [(5, 6), (4, 1), (6, 7)], we should get [(4, 1), (6, 7), (5, 6)].

My way

I have already solved it by making a dictionary that contains the difference as the key and the tuple as the value. But the whole thing is a bit clumsy.

What is a better way?

Upvotes: 8

Views: 9921

Answers (2)

narcissus789
narcissus789

Reputation: 196

Given this list=[('a','b',3),('d','e',3),('e','f',5)], if you'd like to sort by the number in descending order, but break ties (when counts are equal like with the '3' on this example) using ascending alphabetical order of the first element and then the second element repectively, the following code works:

sorted(list,key=lambda x: (-x[2],x[0],x[1]))

Here the '-' sign on the x[2] indicates it needs to be sorted in the descending order. The output will be: [('e', 'f', 5), ('a', 'b', 3), ('d', 'e', 3)]

Upvotes: 2

Martijn Pieters
Martijn Pieters

Reputation: 1123420

Use a key function to sorted() and return a tuple; values will be sorted lexicographically:

sorted(yourlst, key=lambda t: (abs(t[0] - t[1])), t[0]), reverse=True)

I'm using abs() here to calculate a difference, regardless of which of the two integers is larger.

For your sample input, the key produces (1, 5), (3, 4) and (1, 6); in reverse order that puts (1, 6) (for the (6, 7) tuple) before (1, 5) (corresponding with (5, 6)).

Demo:

>>> yourlst = [(5, 6), (4, 1), (6, 7)]
>>> sorted(yourlst, key=lambda t: (abs(t[0] - t[1]), t[0]), reverse=True)
[(4, 1), (6, 7), (5, 6)]

Upvotes: 21

Related Questions