淘宝客网站还可以做吗,网站开发技术简介,自助免费建站,上海新闻综合频道今天你有一个误解#xff0c;hash算法针对的是元素的内容#xff0c;并不是针对指针#xff0c;所以指针不变不等于可hash。
如果你想深究细节的话#xff0c;可以看tuple的源码#xff1a;
static Py_hash_t
tuplehash(PyTupleObject *v)
{
Py_uhash_t x; /* Unsigned for de…你有一个误解hash算法针对的是元素的内容并不是针对指针所以指针不变不等于可hash。
如果你想深究细节的话可以看tuple的源码
static Py_hash_t
tuplehash(PyTupleObject *v)
{
Py_uhash_t x; /* Unsigned for defined overflow behavior. */
Py_hash_t y;
Py_ssize_t len Py_SIZE(v);
PyObject **p;
Py_uhash_t mult _PyHASH_MULTIPLIER;
x 0x345678UL;
p v-ob_item;
while (--len 0) {
y PyObject_Hash(*p);
if (y -1)
return -1;
x (x ^ y) * mult;
/* the cast might truncate len; that doesnt change hash stability */
mult (Py_hash_t)(82520UL len len);
}
x 97531UL;
if (x (Py_uhash_t)-1)
x -2;
return x;
}
注意这里有一个循环tuple会对其中每个元素调用PyObject_Hash将结果进行异或运算再加上一个常量作为整个tuple的hash。
如果tuple中有一个元素是list那么PyObject_Hash将调用list的hash算法然而list定义就表明它根本不实现hash
PyTypeObject PyList_Type {
PyVarObject_HEAD_INIT(PyType_Type, 0)
list,
sizeof(PyListObject),
0,
(destructor)list_dealloc, /* tp_dealloc */
0, /* tp_print */
0, /* tp_getattr */
0, /* tp_setattr */
0, /* tp_reserved */
(reprfunc)list_repr, /* tp_repr */
0, /* tp_as_number */
list_as_sequence, /* tp_as_sequence */
list_as_mapping, /* tp_as_mapping */
PyObject_HashNotImplemented, /* tp_hash */
...
再看 PyObject_HashNotImplemented 的实现
Py_hash_t
PyObject_HashNotImplemented(PyObject *v)
{
PyErr_Format(PyExc_TypeError, unhashable type: %.200s,
Py_TYPE(v)-tp_name);
return -1;
}
这个信息很眼熟吧
结论就是只要tuple中有一个元素是不可hash的不限于list那么整个tuple都是不可hash的。