Obtain difference between two lists of objects in Python using hash
<p>My objective is to get the difference between two lists containing objects.</p>

<p>I have implemented a class named Branch and overwritten its <code>__eq__</code> and <code>__ne__</code> methods as follows:</p>

<pre><code>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
</code></pre>

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

<p>Following code shows the problem:</p>

<pre><code>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
</code></pre>

<p>Output is:</p>

<pre><code>&gt;&gt;&gt; 
branch1
branch3
</code></pre>

<p>However I wish to get as output only branch3 as <code>b1</code> and <code>b1b</code> should be treated as equal.</p>

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

<p>You would need to implement <em>hash</em>, what you choose to is up to you  but the following would work:</p>

<pre><code>def __hash__(self):
    return hash((self.valueFrom , self.valueTo , self.inService))
</code></pre>

<p>All you need to implement is hash and eq:</p>

<pre><code>class Branch(object):
    def __init__(self, name, valueFrom, valueTo, inService=True):
        self.name = name
        self.valueFrom = valueFrom
        self.valueTo = valueTo
        self.inService = inService

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

    def __str__(self):
        return self.name

    def __hash__(self):
        return hash((self.valueFrom, self.valueTo,self.inService))
</code></pre>

python list object set difference