代码之家  ›  专栏  ›  技术社区  ›  afkbowflexin

使Counter将同一类的两个对象视为相同

  •  0
  • afkbowflexin  · 技术社区  · 11 年前

    我正在使用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} 相反这可能吗?我一直在翻阅医生,不知道如何让它发挥作用。

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

    3 回复  |  直到 11 年前
        1
  •  3
  •   flornquake    11 年前

    这个怎么样?

    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
    
        2
  •  1
  •   flornquake    11 年前

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

    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
    
        3
  •  1
  •   Blender    11 年前

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

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

    或者:

    from operator import attrgetter
    
    Counter(map(attrgetter('__name__'), (Type1(), Type2(), Type1())))