Python 中的两个变量具有相同的 id,但不是列表或元组

新手上路,请多包涵

Python 中的两个变量具有相同的 id

 a = 10
b = 10
a is b
>>> True

如果我拿两个 list s:

 a = [1, 2, 3]
b = [1, 2, 3]
a is b
>>> False

根据 此链接,Senderle 回答说不可变对象引用具有相同的 ID,而可变对象(如列表)具有不同的 ID。

所以现在根据他的回答,元组应该有相同的 id——意思是:

 a = (1, 2, 3)
b = (1, 2, 3)
a is b
>>> False

理想情况下,由于元组不可变,它应该返回 True ,但它正在返回 False

解释是什么?

原文由 Ram Vallury 发布,翻译遵循 CC BY-SA 4.0 许可协议

阅读 1k
2 个回答

不可变对象不具有相同的 id ,事实上,对于您单独定义的任何类型的对象而言,情况并非如此。一般来说,每次在 Python 中定义一个对象时,都会创建一个具有新标识的新对象。然而,为了优化(大部分),小整数(-5 到 256 之间)和内部字符串有一些例外,具有特殊长度——通常少于 20 个字符——*它们是单例并且具有相同的 id (实际上是一个对象有多个指针)。您可以像下面这样检查:

 >>> 30 is (20 + 10)
True
>>> 300 is (200 + 100)
False
>>> 'aa' * 2 is 'a' * 4
True
>>> 'aa' * 20 is 'a' * 40
False

对于自定义对象:

 >>> class A:
...    pass
...
>>> A() is A() # Every time you create an instance you'll have a new instance with new identity
False

另请注意, is 运算符将检查对象的身份,而不是值。如果你想检查你应该使用的值 ==

 >>> 300 == 3*100
True

并且由于对于元组或任何可变类型没有这样的优化或实习规则,如果您定义任何大小的两个相同元组,它们将获得自己的身份,因此不同的对象:

 >>> a = (1,)
>>> b = (1,)
>>>
>>> a is b
False

还值得一提的是,即使在迭代器中定义了“单例整数”和“驻留字符串”的规则也是如此。

 >>> a = (100, 700, 400)
>>>
>>> b = (100, 700, 400)
>>>
>>> a[0] is b[0]
True
>>> a[1] is b[1]
False


\* 关于此的一篇很好且详细的文章:http: //guilload.com/python-string-interning/

原文由 Mazdak 发布,翻译遵循 CC BY-SA 4.0 许可协议

不可变 != 相同的对象。*

不可变对象只是一个状态不能改变的对象; 仅此而已。 当创建一个新对象时, 将为其分配一个新地址 因此,检查地址是否等于 is 将返回 False

1 is 1"a" is "a" 返回 True 的事实是由于 Python 执行的 整数缓存 和字符串 实习,所以不要让它混淆;它与所讨论的对象可变/不可变无关。


*空的不可变对象 确实引用同一个对象,它们的 is 确实返回 true,不过这是一个特殊的实现特定情况。

原文由 Dimitris Fasarakis Hilliard 发布,翻译遵循 CC BY-SA 3.0 许可协议

撰写回答
你尚未登录,登录后可以
  • 和开发者交流问题的细节
  • 关注并接收问题和回答的更新提醒
  • 参与内容的编辑和改进,让解决方法与时俱进
推荐问题