I would like to sort a list of tuples based on the two last columns:
mylist = [(33, 36, 84),
(34, 37, 656),
(23, 38, 42)]
I know I can do this like:
final = sorted(mylist, key:lambda x: [ x[1], x[2]])
Now my problem is that I want to compare the second column of my list with a special condition: if the difference between two numbers is less than an offset they should be taken as equal ( 36 == 37 == 38) and the third column should be used to sort the list. The end result I wish to see is:
mylist = [(23, 38, 42)
(33, 36, 84),
(34, 37, 656)]
I was thinking of creating my own integer type and overriding the equal operator. Is this possible? is it overkill? Is there a better way to solve this problem?
I think the easiest way is to create a new class that compares like you want it to:
mylist = [(33, 36, 84),
(34, 37, 656),
(23, 38, 42)]
offset = 2
class Comp(object):
def __init__(self, tup):
self.tup = tup
def __lt__(self, other): # sorted works even if only __lt__ is implemented.
# If the difference is less or equal the offset of the second item compare the third
if abs(self.tup[1] - other.tup[1]) <= offset:
return self.tup[2] < other.tup[2]
# otherwise compare them as usual
else:
return (self.tup[1], self.tup[2]) < (other.tup[1], other.tup[2])
A sample run shows your expected result:
>>> sorted(mylist, key=Comp)
[(23, 38, 42), (33, 36, 84), (34, 37, 656)]
I think it's a bit cleaner than using functools.cmp_to_key
but that's a matter of personal preference.