4

私はcollections.Counterクラスのインスタンスを持っています。また、次のようなオブジェクトもあります。

p1 = Person(name='John')
p2 = Person(name='John')
p3 = Person(name='Jane')

同じ名前の人物オブジェクトは同じ人物カウントをインクリメントする必要があることを考慮して、Counterのインスタンスでこの人物オブジェクトのカウントを保持したいので、すべての人物オブジェクトのリストがある場合:

people = [p1, p2, p3]

そして、私はカウンターにそれを入力します:

c = Counter(people)

私は以下を取得したい:

c[p1] #prints 2
c[p2] #prints 2
c[p3] #prints 1

私の最初の試みは__eq__、人物オブジェクトの新しいメソッドを実装することでした

def __eq__(self, other):
  return self.name == other.name

カウンターオブジェクトは、次のように、キーオブジェクトの同等性に基づいてキーのカウントをインクリメントするように見えるため、これが機能する可能性があると思いました。

c = Counter(['A', 'A', 'B'])
c['A'] #prints 2
c['B'] #prints 1

別の試みは、Counterから継承し、Counterがオブジェクト間の同等性を測定するために使用する基本的なメソッドをオーバーライドする可能性があります。よくわかりませんが、Counterは__contains__そのためのメソッドを使用すると思います。

私の質問は、継承を使用せずにこの動作を取得する方法があるかどうかです。そうでない場合、それを行うための最良の方法は何でしょうか。

4

2 に答える 2

8

また、実装する必要があります__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))

これでコードが機能します。

>>> Counter(people)
Counter({<__main__.Person object at 0x24a7590>: 2, <__main__.Person object at 0x24a75d0>: 1})
于 2013-02-02T22:53:22.747 に答える
2

オブジェクトが例のように単純な場合は、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})
于 2013-02-02T22:58:47.863 に答える