Python 中的两个整数具有相同的 id,但列表或元组则没有

2025-02-13 08:35:00
admin
原创
54
摘要:问题描述:Python 中的两个整数有相同的id:a = 10 b = 10 a is b >>> True 如果我取两个lists:a = [1, 2, 3] b = [1, 2, 3] a is b >>> False 根据此链接, Senderle 回答说不可变对象引...

问题描述:

Python 中的两个整数有相同的id

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

如果我取两个lists:

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

怎么解释呢?


解决方案 1:

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

解决方案 2:

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

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

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


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

解决方案 3:

看一下这段代码:

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

在此处输入图片描述

解决方案 4:

根据文档,不可变变量可能具有相同的 ID,但不能保证它们确实如此。可变变量始终具有不同的 ID。

https://docs.python.org/3/reference/datamodel.html#objects-values-and-types

类型几乎影响对象行为的所有方面。甚至对象身份的重要性在某种意义上也受到影响:对于不可变类型,计算新值的操作实际上可能返回对具有相同类型和值的任何现有对象的引用,而对于可变对象,这是不允许的。

在以前的 Python 版本中,元组被分配了不同的 ID。(3.7 之前)

从 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

解决方案 5:

检查下面的代码。当我们将 tupils 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?。
这里还讨论了另一种情况。

相关推荐
  政府信创国产化的10大政策解读一、信创国产化的背景与意义信创国产化,即信息技术应用创新国产化,是当前中国信息技术领域的一个重要发展方向。其核心在于通过自主研发和创新,实现信息技术应用的自主可控,减少对外部技术的依赖,并规避潜在的技术制裁和风险。随着全球信息技术竞争的加剧,以及某些国家对中国在科技领域的打压,信创国产化显...
工程项目管理   1565  
  为什么项目管理通常仍然耗时且低效?您是否还在反复更新电子表格、淹没在便利贴中并参加每周更新会议?这确实是耗费时间和精力。借助软件工具的帮助,您可以一目了然地全面了解您的项目。如今,国内外有足够多优秀的项目管理软件可以帮助您掌控每个项目。什么是项目管理软件?项目管理软件是广泛行业用于项目规划、资源分配和调度的软件。它使项...
项目管理软件   1354  
  信创国产芯片作为信息技术创新的核心领域,对于推动国家自主可控生态建设具有至关重要的意义。在全球科技竞争日益激烈的背景下,实现信息技术的自主可控,摆脱对国外技术的依赖,已成为保障国家信息安全和产业可持续发展的关键。国产芯片作为信创产业的基石,其发展水平直接影响着整个信创生态的构建与完善。通过不断提升国产芯片的技术实力、产...
国产信创系统   21  
  信创生态建设旨在实现信息技术领域的自主创新和安全可控,涵盖了从硬件到软件的全产业链。随着数字化转型的加速,信创生态建设的重要性日益凸显,它不仅关乎国家的信息安全,更是推动产业升级和经济高质量发展的关键力量。然而,在推进信创生态建设的过程中,面临着诸多复杂且严峻的挑战,需要深入剖析并寻找切实可行的解决方案。技术创新难题技...
信创操作系统   27  
  信创产业作为国家信息技术创新发展的重要领域,对于保障国家信息安全、推动产业升级具有关键意义。而国产芯片作为信创产业的核心基石,其研发进展备受关注。在信创国产芯片的研发征程中,面临着诸多复杂且艰巨的难点,这些难点犹如一道道关卡,阻碍着国产芯片的快速发展。然而,科研人员和相关企业并未退缩,积极探索并提出了一系列切实可行的解...
国产化替代产品目录   28  
热门文章
项目管理软件有哪些?
云禅道AD
禅道项目管理软件

云端的项目管理软件

尊享禅道项目软件收费版功能

无需维护,随时随地协同办公

内置subversion和git源码管理

每天备份,随时转为私有部署

免费试用