質問

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})

他のヒント

If your objects are simple as in your example use collections.namedtuple

from collections import Counter, namedtuple
Person = namedtuple('Person','name')

n1 = Person(name='John')
n2 = Person(name='John')
n3 = Person(name='Jane')
Counter((n1,n2,n3))
# Counter({Person(name='John'): 2, Person(name='Jane'): 1})
ライセンス: CC-BY-SA帰属
所属していません StackOverflow
scroll top