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

zc0qhyus  于 2022-11-26  发布在  Python
关注(0)|答案(5)|浏览(275)

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
有什么解释?

imzjd6km

imzjd6km1#

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

同样值得一提的是,“单例整数”和“interned字符串”的规则即使是在迭代器中定义的也是正确的。

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

v9tzhpje2#

不可变!=相同对象*

不可变对象就是其状态不能改变的对象;和is的地址,将返回False。* 当一个新对象被创建时,一个新地址将被分配给它
1 is 1"a" is "a"返回True的事实是由Python执行的integer caching和字符串interning引起的,所以不要让它混淆;它与所讨论的对象是可变的/不可变的无关。

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

2skhul333#

看一看下面的代码:

>>> 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,我强烈建议你在Python在线教程中一步一步地运行上面的代码片段。内存中对象的图形表示将为你提供对这个问题的更深入的了解(我附上了一张截图)。

flseospp

flseospp4#

检查下面的代码.. tupilsab在我们重新分配它们的旧值时,仍保留它们的旧引用(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)
>>>

**阅读本文后,请检查链接Why don't tuples get the same ID when assigned the same values?。此处还讨论了另一个案例。

g9icjywg

g9icjywg5#

根据文档,不可变对象可能具有相同的id,但不能保证它们确实如此。可变对象总是具有不同的id。
https://docs.python.org/3/reference/datamodel.html#objects-values-and-types
类型几乎影响对象行为的所有方面,甚至对象身份的重要性也在某种意义上受到影响:对于不可变类型,计算新值的操作实际上可以返回对具有相同类型和值的任何现有对象的引用,而对于可变对象,这是不允许的。
在Python的早期版本中,元组被分配了不同的ID。
从Python 3.7+开始,两个赋值了相同元组的变量可以有相同的id:

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

大于256的整数也有不同的id:

>>>a = 123
>>>b = 123
>>>a is b
True
>>>
>>>a = 257
>>>b = 257
>>>a is b
False

相关问题