0

我正在使用 collections.Counter。到目前为止它很棒,除了我希望它可以将同一类的对象计算为相同的对象。我怎样才能做到这一点?我尝试覆盖类上的hash () 方法,以便所有实例的哈希值相同。现在,如果我这样做Counter([Type1(), Type1(), Type2(), Type2()]),它会返回{<Type1 object at...>:1,<Type1 object at...>:1,<Type2 object at...>:1,<Type2 object at...>:1},我希望它返回类似的东西{"Type1":2, "Type2":2}。这可能吗?我正在浏览文档,无法弄清楚如何使其工作。

我应该补充一点,我使用的类本质上是常量值的包装器。将它们包装在一个类中更方便。在任何情况下,一个 Type1 对象都不会与另一个 Type1 对象不同。

4

3 回答 3

3

这个怎么样?

Counter(type(x) for x in [Type1(), Type1(), Type2(), Type2()])

这是你将如何使用它:

>>> type_counter = Counter(type(x) for x in [Type1(), Type1(), Type2(), Type2()])
>>> type_counter
Counter({<class '__main__.Type2'>: 2, <class '__main__.Type1'>: 2})
>>> type_counter[Type1]
2
>>> type_counter[type(Type2())]
2
于 2013-09-09T22:47:14.073 回答
1

如果要按类名对它们进行分组,可以使用__name__属性:

Counter(i.__name__ for i in (Type1(), Type2(), Type1()))

或者:

from operator import attrgetter

Counter(map(attrgetter('__name__'), (Type1(), Type2(), Type1())))
于 2013-09-09T23:01:15.180 回答
1

再次阅读您的问题后,我添加了一种可能更适合您需求的不同方法。

Counter是一个字典,Python中的字典使用__hash__方法和__eq__方法来比较对象。因此,如果您想要始终比较相等并且可以用作字典键的对象,则需要定义这两种方法。

# (Python 3)
class Type1:
    def __eq__(self, other):
        if isinstance(other, Type1):
            return True
        return super().__eq__(other)

    def __hash__(self):
        return 1329916036    # anything constant

如果你对 做同样的事情Type2,你可以像这样计算实例Counter

>>> mycounter = Counter([Type1(), Type1(), Type2(), Type2()])
>>> mycounter
Counter({<__main__.Type1 object at ...>: 2, <__main__.Type2 object at ...>: 2})
>>> mycounter[Type1()]
2
于 2013-09-09T23:31:06.513 回答