I have a list of objects which I want to turn into a set. My objects contain a few fields that some of which are o.id
and o.area
. I want two objects to be equal if these two fields are the same. ie: o1==o2
if and only if o1.area==o2.area and o1.id==o2.id
.
I tried over-writing __eq__
and __cmp__
but I get the error: TypeError: unhashable instance
.
What should I over-write?
How to Create a Set. The most common way of creating a set in Python is by using the built-in set() function. The set() function takes in an iterable and yields a list of objects which will be inserted into the set. The {} syntax places the objects themselves into the set.
Sets are unordered. Set elements are unique. Duplicate elements are not allowed. A set itself may be modified, but the elements contained in the set must be of an immutable type.
Creating Python SetsA set is created by placing all the items (elements) inside curly braces {} , separated by comma, or by using the built-in set() function. It can have any number of items and they may be of different types (integer, float, tuple, string etc.).
Define the __hash__
method to return a meaningful hash based on the id and area fields. E.g.:
def __hash__(self): return hash(self.id) ^ hash(self.area)
"TypeError: unhashable instance." error is probably due to old-style class definition i.e.:
class A: pass
Use new style instead:
class A(object): pass
If you override __cmp__ function you should override __hash__ for using your object in sets. In the other case hash considers all object instances as unequal and __cmp__ function will never be called.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With