emilchess
emilchess

Reputation: 127

__key__ parameter for classes in Python

I have an array of vectors and I want to sort them by length:

class Vector:

     def __init__(self, x, y):
       self.x, self.y = x, y

     def __add__(a, b):
       return Vector(a.x + b.x, a.y + b.y)

     def __str__(a):
       return str(a.x) + ' ' + str(a.y) + '\n'

     def __key__(self):
       return self.x * self.x + self.y * self.y


a = []
a.append(Vector(1,2))
a.append(Vector(1, 1))
a.sort()
print("".join(map(str,a)))

It says: "unorderable types: Vector() < Vector()" It wants me to create lt, gt.. methods. But I want to sort without using cmp. Is it possible?

Upvotes: 8

Views: 5331

Answers (3)

Oleksii Kachaiev
Oleksii Kachaiev

Reputation: 6234

You have two variants here: implement __cmp__ function in Vector class or perform sorting this way:

...
a.sort(key=Vector.__key__) 

Upvotes: 6

mgilson
mgilson

Reputation: 309909

I would implement __lt__ and __eq__ and then use the functools.total_ordering class decorator to get the rest of the comparison methods.

If it doesn't make sense to have your vectors ordered like that, then you can always just use the key keyword to sort (or sorted for that matter):

mylist.sort(key = lambda v: v.x**2 + v.y**2)

Upvotes: 8

C&#233;dric Julien
C&#233;dric Julien

Reputation: 80761

Python docs says that lt/le/gt/ge/eq/ne are

[...] the so-called “rich comparison” methods, and are called for comparison operators in preference to __cmp__()

If you implement a __cmp__(self, other) method, it should be used for comparison/sort operations.

Upvotes: 2

Related Questions