[英]Python Comparing 2 list and 2 tuple with equality sign
最近我在Python中学习了更多关于哈希的知识,我在这个博客中说到:
假设一个Python程序有2个列表。 如果我们需要考虑比较这两个列表,你会怎么做? 比较每个元素? 嗯,这听起来很简单,但也很慢!
Python有一个更聪明的方法来做到这一点。 当在程序中构造元组时,Python解释器会在其内存中计算其哈希值。 如果在2个元组之间进行比较,它只是比较哈希值,它知道它们是否相等!
所以我对这些陈述感到很困惑。
首先,我们这样做: [1, 2, 3] == [1, 2, 3]
那么这种平等如何运作? 它是否计算哈希值然后进行比较?
第二,当我们做的时候有什么不同:
[1, 2, 3] == [1, 2, 3]
和(1, 2, 3) == (1, 2, 3)
?
因为当我试图用timeit找到执行时间时,我得到了这个结果:
$ python3.5 -m timeit '[1, 2, 3] == [1, 2, 3]'
10000000 loops, best of 3: 0.14 usec per loop
$ python3.5 -m timeit '(1, 2, 3) == (1, 2, 3)'
10000000 loops, best of 3: 0.0301 usec per loop
那么为什么时间差异从列表的0.14
到元组的0.03
,比列表快。
好吧,你的一些困惑是,你正在阅读的博客文章是错的。 关于多件事。 试着忘记你曾经读过它(除了记住网站和作者的名字,所以你知道将来要避免它们)。
确实,元组是可清除的,列表不是,但这与它们的相等测试函数无关。 并且它肯定不是“它只是比较哈希值,它知道它们是否相等!” 哈希冲突发生,忽略它们会导致可怕的错误,幸运的是Python的开发人员并不是那么愚蠢。 事实上,Python在初始化时计算哈希值并不是真的。 *
元组和列表之间实际上存在一个显着差异(在CPython中,从3.6开始),但它通常没有太大区别:列表在开始时作为优化对不等长度进行额外检查,但同样的检查结果对元组来说是一种悲观, **所以它从那里被删除了。
另一个,通常更为重要的区别是,源中的元组文字被编译为常量值,同一元组文字的单独副本被折叠到同一个常量对象中; 由于显而易见的原因,列表不会发生这种情况。
事实上,这就是你真的与你的测试timeit
。 在我的笔记本电脑上,比较元组需要95ns,而比较列表需要169ns - 但是将其分解,实际上比较为93ns,另外还有38ns来创建每个列表。 为了使其公平比较,您必须将创建移动到设置步骤,然后比较循环内已存在的值。 (或者,当然,你可能不想公平 - 你发现了一个有用的事实,即每次使用元组常量而不是创建一个新列表时,你节省了相当大的一微秒。)
除此之外,他们基本上做同样的事情。 将C源转换为类似Python的伪代码(并删除所有错误处理,以及使相同功能适用于<
,等等的东西):
for i in range(min(len(v), len(w))):
if v[i] != w[i]:
break
else:
return len(v) == len(w)
return False
等效列表如下:
if len(v) != len(w):
return False
for i in range(min(len(v), len(w))):
if v[i] != w[i]:
break
else:
return True
return False
*实际上,与字符串不同,元组甚至不会缓存它们的哈希值; 如果你反复调用hash
,它会继续重新计算它。 请参阅问题9685 ,其中更改的修补程序被拒绝,因为它减慢了某些基准测试并且没有加快任何人都能找到的速度。
**不是因为实现有任何固有的东西,而是因为人们经常比较不同长度的列表,但很少使用元组。
答案也在那篇文章中给出:)
这是证明:
>>> l1=[1,2,3]
>>> l2=[1,2,3]
>>>
>>> hash(l1) #since list is not hashable
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
TypeError: unhashable type: 'list'
>>> t=(1,2,3)
>>> t2=(1,2,3)
>>> hash(t)
2528502973977326415
>>> hash(t2)
2528502973977326415
>>>
在上面当你在列表上调用hash时它会给你TypeError,因为它不可以和两个列表python相等,检查它的内部值会导致花费很多时间
在元组的情况下,它计算哈希值和两个具有相同哈希值的类似元组,因此python只比较元组的哈希值,所以它比列表快得多
从给定的文章
Python有一个更聪明的方法来做到这一点。 当在程序中构造元组时,Python解释器会在其内存中计算其哈希值。 如果在2个元组之间进行比较,它只是比较哈希值,它知道它们是否相等!
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.