What methods need to be overridden/implemented when making user-defined classes sortable and/or hashable in python?
What are the gotchas to watch out for?
I type dir({}) into my interpreter to get a list of methods on built-in dicts. Of those, I assume I need to some implement some subset of
['__cmp__', '__eq__', '__ge__', '__gt__', '__hash__', '__le__', '__lt__', '__ne__']
Is there a difference in which methods must be implemented for Python3 as opposed to Python2?
Answers:
Thank you for visiting the Q&A section on Magenaut. Please note that all the answers may not help you solve the issue immediately. So please treat them as advisements. If you found the post helpful (or not), leave a comment & I’ll get back to you as soon as possible.
Method 1
I almost posted this as a comment to the other answers but it’s really an answer in and of itself.
To make your items sortable, they only need to implement __lt__. That’s the only method used by the built in sort.
The other comparisons or functools.total_ordering are only needed if you actually want to use the comparison operators with your class.
To make your items hashable, you implement __hash__ as others noted. You should also implement __eq__ in a compatible way — items that are equivalent should hash the same.
Method 2
There isn’t any difference between Python 2 and 3.
For sortability:
You should define comparision methods. This makes your items sortable. Generally, you shouldn’t prefer __cmp__().
I usually use functools.total_ordering decorator.
functools.total_ordering(cls) Given a class defining one or more rich
comparison ordering methods, this class decorator supplies the rest.
This simplifies the effort involved in specifying all of the possible
rich comparison operations:The class must define one of
__lt__(),__le__(),__gt__(), or
__ge__(). In addition, the class should supply an__eq__()method.
You should be careful that your comparison methods do not have any side effects. (change any of the values of the object)
For hashing:
You should implement __hash__() method. I think the best way is returning hash(repr(self)), so your hash would be unique.
Method 3
There are a few ways of marking your object sortable. First – rich comparison, defined by a set of functions:
object.__lt__(self, other) object.__le__(self, other) object.__eq__(self, other) object.__ne__(self, other) object.__gt__(self, other) object.__ge__(self, other)
Also it is possible to define only one function:
object.__cmp__(self, other)
And the last should be defined if you want to define custom __hash__ function. See the doc.
Method 4
Implement __lt__(self,other) method is the answer to make your class sortable.
It can be used for not only the built-in method sorted(iterable), but also priority queue via heapq module.
In addition, I don’t like python’s design, so many '__ge__', '__gt__', '__le__', '__lt__', '__ne__' methods are not intuitive at all !
As a contrast, Java’s Interface Comparable<T> (see java doc) returns a negative integer, zero, or a positive integer as this object is less than, equal to, or greater than the specified object, which is direct and friendly!
All methods was sourced from stackoverflow.com or stackexchange.com, is licensed under cc by-sa 2.5, cc by-sa 3.0 and cc by-sa 4.0