Cedric Cedric - 2 months ago 8
Python Question

Obtain difference between two lists of objects in Python using hash

My objective is to get the difference between two lists containing objects.

I have implemented a class named Branch and overwritten its

__eq__
and
__ne__
methods as follows:

class Branch(object):
def __str__(self):
return self.name

def __eq__(self, other):
if isinstance(other, Branch):
return (self.valueFrom == other.valueFrom) \
and (self.valueTo == other.valueTo) \
and (self.inService == other.inService)
return NotImplemented

def __ne__(self, other):
result = self.__eq__(other)
if result is NotImplemented:
return result
return not result

def __init__(self, name, valueFrom, valueTo, inService=True):
self.name = name
self.valueFrom = valueFrom
self.valueTo = valueTo
self.inService = inService


My first attempt was to use the method
difference
from the
set
type. However it appears this is not possible as it uses the hash of the object and not the
__eq__
method as I would like to.

Following code shows the problem:

b1 = Branch("branch1", 1, 2)
b1b = Branch("equal to branch1", 1, 2)
b2 = Branch("branch2", 2, 3)
b3 = Branch("branch3", 3, 1)
b3_off = Branch("branch3 not in service", 3, 1, False)

l1 =[b1,b2,b3]
l2 =[b1b,b2,b3_off]

difference = set(l1).difference(l2)
for branch in difference:
print branch


Output is:

>>>
branch1
branch3


However I wish to get as output only branch3 as
b1
and
b1b
should be treated as equal.

Is it possible to use sets to resolve this? Or should I approach the problem from a different perspective?

Answer

You would need to implement hash, what you choose to is up to you but the following would work:

def __hash__(self):
    return hash((self.valueFrom , self.valueTo , self.inService))