I have and instance of collections.Counter class, also i have some objects like:
p1 = Person(name='John')
p2 = Person(name='John')
p3 = Person(name='Jane')
I want to hold the counts for this person objects in a instance of Counter, taking into account that person objects with same names must increment the same person count, so if i have a list with all person objects:
people = [p1, p2, p3]
and i populate my counter with it:
c = Counter(people)
i want to get the following:
c[p1] #prints 2
c[p2] #prints 2
c[p3] #prints 1
My first attempt was to implement a new __eq__
method for person objects
def __eq__(self, other):
return self.name == other.name
I thought that this could work because counter objects seems like increment the counts for keys based on the equality of the key objects, like in:
c = Counter(['A', 'A', 'B'])
c['A'] #prints 2
c['B'] #prints 1
Another attempt could be inherit from Counter and override the underlying method that
Counter uses for measure the equality between objects , i am not sure but i think
Counter uses __contains__
method for that.
My question is if there are any way to gets this behavior without using inheritance and if not, what could be the best way to do it?.
You also have to implement __hash__
:
class Person(object):
def __init__(self, name=None, address=None):
self.name = name
self.address = address
def __eq__(self, other):
return self.name == other.name and self.address == other.address
def __hash__(self):
return hash((self.name, self.address))
Now your code works:
>>> Counter(people)
Counter({<__main__.Person object at 0x24a7590>: 2, <__main__.Person object at 0x24a75d0>: 1})