嗯,你的部分困惑是你读的博客文章是错的。关于很多事情。试着忘记你曾经读过它(除了记住网站和作者的名字,这样你就知道以后要避开它们)。在
元组是可以散列的,而列表是不可哈希的,但这与它们的等式测试函数无关。“它只是比较散列值,然后知道它们是否相等”,这当然不是真的哈希冲突会发生,忽略它们会导致可怕的错误,幸运的是Python的开发人员并没有那么蠢。实际上,Python在初始化时计算散列值是不正确的
实际上,在元组和列表之间有一个显著的区别(在CPython中,从3.6开始),但它通常没有太大区别:列表在开始时作为一个优化对不相等长度进行了额外检查,但同样的检查结果是对元组的一种悲观,**因此它被从那里删除了。在
另一个通常更重要的区别是源代码中的元组文本被编译成常量值,同一元组文本的单独副本被折叠到同一个常量对象中;由于明显的原因,列表不会发生这种情况。在
事实上,这就是你用你的timeit来测试的。在我的笔记本电脑上,比较元组需要95纳秒,而比较列表需要169纳秒,但将其分解为93纳秒,再加上额外的38纳秒来创建每个列表。要使其成为一个公平的比较,您必须将创建移动到设置步骤,然后比较循环中已经存在的值。(或者,当然,公平地说,您可能不想您发现了一个有用的事实,即每次使用元组常量而不是创建新列表时,都会节省相当多的微秒)
除此之外,他们基本上也是这样做的。将the C source转换为类似Python的伪代码(并删除所有错误处理,以及使同一函数为
if v[i] != w[i]:
break
else:
return len(v) == len(w)
return False
*事实上,与字符串不同,元组甚至不缓存它们的哈希值;如果反复调用hash,它会不断地重新计算它。请参见issue 9685,其中一个要更改的补丁被拒绝了,因为它减慢了一些基准测试的速度,而且没有加快任何人可以找到的东西。
**这并不是因为实现的固有特性,而是因为人们经常比较不同长度的列表,但很少使用元组。