我正在使用collections.Counter。到目前为止它很棒,除了我想要它计算相同类的对象。我怎样才能做到这一点?我尝试重写类上的哈希()方法,以便所有实例都将哈希相同。现在,如果我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对象不同。
答案 0 :(得分: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
答案 1 :(得分:1)
如果要按类名对它们进行分组,可以使用__name__
属性:
Counter(i.__name__ for i in (Type1(), Type2(), Type1()))
或者:
from operator import attrgetter
Counter(map(attrgetter('__name__'), (Type1(), Type2(), Type1())))
答案 2 :(得分: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