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

Python-当重复项被标识时,set或frozenset使用哪个对象?

  •  2
  • MikeRand  · 技术社区  · 14 年前

    我有一个用户定义的类 MyClass 有一个 __hash__ __eq__ 确保例如:

    >>> a = MyClass([100, 99, 98, 97])
    >>> b = MyClass([99, 98, 97, 100])
    >>> a.__hash__() == b.__hash__()
    True
    >>> a == b
    True
    

    问题:如果我这样做:

    >>> x = [a, b]
    >>> set(x)
    

    我能指望吗 set 保持 a ? 是布景吗 __init__ 遍历 x 整齐?或者我需要担心 b 随机?

    谢谢,

    迈克

    3 回复  |  直到 14 年前
        1
  •  3
  •   Chris Morgan    14 年前

    在这些基于散列的情况下,它同时使用 __hash__ __eq__ .

    如果 __散列__ __情商__ 两者都是一样的,然后它在iterable中到达的第一个被获取。当它到达下一个时,它会检查它是否已经拥有它并决定是。

    >>> class Same(object):
    ...     def __init__(self, value):
    ...         self.value = value
    ...     def __hash__(self):
    ...         return 42
    ...     def __eq__(self, other):
    ...         return True
    ...     def __repr__(self):
    ...         return 'Same(%r)' % self.value
    >>> set([Same(2), Same(1)])
    set([Same(2)])
    >>> set([Same(1), Same(2)])
    set([Same(1)])
    

    用一个 dict ,它变得更有趣:

    >>> {Same(1): 1, Same(2): 2}
    {Same(1): 2}
    >>> {Same(1): 2, Same(2): 1}
    {Same(1): 1}
    >>> {Same(2): 1, Same(2): 2}
    {Same(2): 2}
    >>> {Same(2): 2, Same(2): 1}
    {Same(2): 1}
    >>> {Same(2): 2, Same(2): 1}
    {Same(2): 1}
    

    你应该能猜到这里发生了什么。它存储第一个项,然后第二个项的散列/等式是相同的;但是,它有一个不同的值,所以它存储这个值。这个 价值 始终被覆盖,无论它们是否匹配:

    >>> {Same(1): Same(2), Same(3): Same(4)}
    {Same(1): Same(4)}
    

    我希望这会有帮助。

        2
  •  1
  •   Ignacio Vazquez-Abrams    14 年前

    set (和 dict )不仅要检查散列的相等性,还要考虑对象本身的相等性。

        3
  •  1
  •   daniel    14 年前

    我相信set()需要 搞砸 情商 被推翻。在这种情况下,可以有hash(a)==hash(b),但仍然有a!=b,假设您定义了 情商 以这种方式