In [1]: x = set()
In [2]: pos = collections.namedtuple('Position', ['x','y'])
In [4]: x.add(pos(1,1))
In [5]: x
Out[5]: {Position(x=1, y=1)}
In [6]: pos(1,1) in x
Out[6]: True
In [8]: pos(1,2) in x
Out[8]: False
我并不期望第6行pos(1,1) in x
能正常工作,因为pos(1,1)每次创建的对象ID都不一样。
In [9]: id(pos(1,1))
Out[9]: 140290954200696
In [10]: id(pos(1,1))
Out[10]: 140290954171016
在这种情况下,set in
操作符如何处理命名元组?它是否检查命名元组的内容?
2条答案
按热度按时间bmp9r5qi1#
namedtuple并不特殊。元素应该完全相等(
__eq__
),并且必须具有类似的hash
才能通过包含测试。如果您有兴趣查看此处的实现,
set().__contains__(y)
首先必须计算y
的hash
值。但是单独计算
hash
并不能说明元素是否相等。这意味着如果散列值相等,则需要
__eq__
检查来确认元素是否完全相等。请注意,我的答案完全基于Cpython实现。
4ioopgfo2#
可散列对象的元组是可散列的,因此它可以用作集合的成员,从而通过
in
检查。由于您使用数字作为元组值(显然是可散列的),因此散列整个元组没有问题。