简体   繁体   English

命名元组存在于哈希集中

[英]Named tuples existence in a hashset

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

I was not expecting Line 6 pos(1,1) in x to work.我没想到pos(1,1) in x可以工作。 Since it does seem that pos(1,1) creates an object with a different object id every time.因为 pos(1,1) 似乎每次都会创建一个 object 和不同的 object id。

In [9]: id(pos(1,1))
Out[9]: 140290954200696
In [10]: id(pos(1,1))
Out[10]: 140290954171016

How does the set in operator work on named tuples in this case?在这种情况下,set in运算符如何处理命名元组? Does it check the contents of namedtuple?它会检查 namedtuple 的内容吗?

namedtuple is not special. namedtuple 并不特别。 The element should be exactly equal( __eq__ ) and must have similar hash to pass the containment test.该元素应该完全相等( __eq__ )并且必须具有相似的hash才能通过包含测试。

>>> hash(pos(1, 1)) == hash(pos(1, 1))
True
>>> pos(1, 1) == pos(1, 1)
True

If you are interested see the implementation here , set().__contains__(y) first have to compute the hash value of y .如果您有兴趣, 请参阅此处的实现set().__contains__(y)首先必须计算yhash值。

static int
set_contains_key(PySetObject *so, PyObject *key)
{
    Py_hash_t hash;

    if (!PyUnicode_CheckExact(key) ||
        (hash = _PyASCIIObject_CAST(key)->hash) == -1) {
        hash = PyObject_Hash(key);
        if (hash == -1)
            return -1;
    }
    return set_contains_entry(so, key, hash);
}

but computing hash alone does not says whether the element are equal.但是单独计算hash并不能说明元素是否相等。 For example例如

>>> hash(-1)
-2
>>> hash(-2)
-2

Which means that if the hash values are equal then __eq__ check is required to confirm if the elements are exactly equal .这意味着如果 hash 值相等,则需要进行__eq__检查以确认元素是否完全相等

Please note that my answer is purely based on Cpython implementation.请注意,我的回答完全基于 Cpython 实现。

A tuple of hashable objects is hashable, so it can be used as a member of a set and therefore pass the in check.可散列对象的元组是可散列的,因此它可以用作集合的成员,因此可以通过in检查。
Since you are using numbers as tuple values, which are obviously hashable, there is no problem hashing the entire tuple.由于您使用数字作为元组值,这显然是可散列的,因此散列整个元组没有问题。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM