Python 技巧3:对象比较:“is” vs “==”
这篇文章由伟兄整理供稿。另外,欢迎访问并关注他的博客:https://jl-zhenlaixiaowei.blog.csdn.net/
当我还是个孩子的时候,我们的邻居有两只双胞胎猫。他们看起来一模一样——同样的炭黑色皮毛和同样刺眼的绿色眼睛。
撇开一些性格怪癖不谈,你不能仅仅看它们就区分它们。但当然,它们是两只不同的猫,两个不同的生物,尽管它们看起来完全一样。
这使我想到了相等和相同之间的含义差异。这种差异对于理解 Python 的 is 和 == 比较运算符的行为方式至关重要。
== 运算符通过检查是否相等来进行比较:如果这些猫是 Python 对象并且我们将它们与 == 运算符进行比较,我们会得到“两只猫相等”作为答案。
然而,is 运算符比较身份(同一性):如果我们将猫与 is 运算符进行比较,我们会得到“这是两只不同的猫”作为答案。
但在我纠结于这个麻绳猫的类比之前,让我们看一下一些真正的 Python 代码。
首先,我们将创建一个新的列表对象并将其命名为 a,然后定义另一个指向同一个列表对象的变量 (b):
In [2]: a = [1, 2, 3]
In [3]: b = a
让我们检查这两个变量。我们可以看到它们指向外观相同的列表:
In [4]: a
Out[4]: [1, 2, 3]
In [5]: b
Out[5]: [1, 2, 3]
因为这两个列表对象看起来相同,所以当我们使用 == 运算符比较它们是否相等时,我们将得到预期的结果:
In [6]: a == b
Out[6]: True
但是,这并不能告诉我们 a 和 b 是否实际上指向同一个对象。
当然,我们知道它们是指向同一个对象,是因为我们之前指定了它们,但假设我们不知道——我们怎么会发现呢?
答案是用 is 运算符比较这两个变量。这证实了这两个变量实际上都指向一个列表对象:
In [7]: a is b
Out[7]: True
让我们看看当我们创建列表对象的相同副本时会发生什么。我们可以通过在现有列表上调用 list() 来创建一个我们将命名为 c 的副本:
In [8]: c = list(a)
您将再次看到我们刚刚创建的新列表看起来与 a 和 b 指向的列表对象相同:
In [9]: c
Out[9]: [1, 2, 3]
现在这就是有趣的地方。让我们使用 == 操作符将我们的列表副本 c 与初始列表 a 进行比较。你希望看到什么答案?
In [10]: a == c
Out[10]: True
好吧,我希望这是你所期望的。这个结果告诉我们的是 c 和 a 具有相同的内容。Python 认为它们是平等的。但它们实际上指向的是同一个对象吗?让我们用 is 运算符找出答案:
In [11]: a is c
Out[11]: False
砰!这是我们得到不同结果的所在。Python 告诉我们 c 和 a 指向两个不同的对象,即使它们的内容可能相同。
因此,回顾一下,让我们尝试将 is 和 == 之间的区别分解为两个简短的定义:
如果两个变量指向同一个(相同的)对象,则 is 表达式的计算结果为 True
如果变量引用的对象相等(具有相同的内容),则 == 表达式的计算结果为 True
附注:本文译自《Python Tricks:THE BOOK》 作者 :Dan Bade