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

时间:2016-07-04 17:21:10

标签: python python-3.x tuples identity python-internals

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

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

如果我带两个list s:

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

根据this link Senderle回答说,不可变对象引用具有相同的id,而像列表这样的可变对象具有不同的id。

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

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

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

解释是什么?

4 个答案:

答案 0 :(得分:55)

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

由于对于元组(其他类型)没有这样的规则,如果你定义任意大小的两个相同的元组,他们将得到他们自己的id:

>>> 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

答案 1 :(得分:20)

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

An immutable object is simply an object whose state cannot be altered;就是这样。 创建新对象时,将为其分配新地址因此,检查地址是否与is相等将返回{{1 }}。

False1 is 1返回"a" is "a"的事实归因于integer caching和字符串interning由Python执行,所以不要让它混淆你;它与有问题的对象无关是可变的/不可变的。

*空的不可变对象do refer to the same object及其True确实返回true,但这是一个特殊的实现特定情况。

答案 2 :(得分:15)

看看这段代码:

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

为了弄清楚为什么a is c被评估为True,而a is b产生False,我强烈建议您逐步执行上面的代码段Online Python Tutor。内存中对象的图形表示将为您提供对此问题的更深入了解(我附上了截图)。

enter image description here

答案 3 :(得分:0)

检查以下代码.. 当我们重新分配旧值时,学生 a b 会保留旧的引用(ID)。 (但是,这不会是列表,因为它们是可以修复的)

最初 a b 具有相同的值((1,2)),但它们具有不同的ID。在更改其值后,当我们将值(1,2)重新分配给 a b 时,它们现在引用自己相同的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)
>>> 

**查看链接Why don't tuples get the same ID when assigned the same values?  读完之后也是这样。这里也讨论了另一个案例。