繁体   English   中英

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

[英]Two variables in Python have same id, but not lists or tuples

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

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

如果我拿两个list

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

解释是什么?

不可变对象没有相同的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/

不可变!=同一个对象。 *

不可变对象只是状态不能改变的对象; 这就是全部。 当一个新对象被创建时,一个新的地址将被分配给它 因此,检查地址是否与is相等将返回False

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


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

看看这段代码:

>>> a = (1, 2, 3)
>>> b = (1, 2, 3)
>>> c = a
>>> id(a)
178153080L
>>> id(b)
178098040L
>>> id(c)
178153080L

为了弄清楚为什么a is c被评估为Truea is b产生False我强烈建议您在Online Python Tutor 中逐步运行上面的代码片段。 内存中对象的图形表示将使您更深入地了解这个问题(我附上了截图)。

在此处输入图片说明

检查下面的代码.. tupil ab在我们将其旧值分配回时保留其旧引用(ID)。 (但是,列表不会是这种情况,因为它们是可变的)

最初ab具有相同的值( (1,2) ),但它们具有不同的 ID。 更改它们的值后,当我们将值 (1,2) 重新分配给ab 时,它们现在引用的是他们自己的相同 ID(分别为 88264264 和 88283400)。

>>> a = (1,2)
>>> b = (1,2)
>>> a , b
((1, 2), (1, 2))
>>> id(a)
88264264
>>> id(b)
88283400
>>> a = (3,4)
>>> b = (3,4)
>>> id(a)
88280008
>>> id(b)
88264328
>>> a = (1,2)
>>> b = (1,2)
>>> id(a)
88264264
>>> id(b)
88283400
>>> a , b
((1, 2), (1, 2))
>>> id(a) , id(b)
(88264264, 88283400)
>>> 

**检查链接为什么元组在分配相同的值时不会获得相同的 ID? 也是在读完这篇之后。 这里还讨论了另一个案例。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM