比较两个变量是否在python中引用了同一对象


Answers:


133

就是这样isx is y返回Trueif xy是否为同一对象。


6
在示例中,x is z返回False。但是,如果给x和z分配了相同的值而不是列表(例如x, z = 13, 13),则x is z返回True。这是为什么?
法案

12
@Bill:这是python如何处理整数的伪像。Python将整数对象分配给which xzpoint。由于小整数很常见(错误值为-1,因此每次实际索引时为0,小数通常是合理的默认值),Python通过预分配小数(-5至256)进行优化,并重用相同的整数对象。因此,您的示例仅适用于此范围内的数字。尝试分配更大的值,即270。有关更多信息
TED

1
@AndresR不,那是错误的。is检查两个名称是否引用相同的存储位置。它与对象本身无关。拥有不变的对象(如字符串)很容易,这些对象相等但不存储在同一位置,例如''a'*10000 is 'a' * 10000False。
Jochen Ritzel'4

1
@JochenRitzel您完全正确,谢谢您的评论!因此,我不知道发生了什么"af" is "af"() is ()...为什么它们共享相同的内存位置?
AndresR

2
@AndreasR对于代码中的文字字符串/数字,编译器会检查它们仅存在一次并重用它们。诸如(),None,True,False等特殊值也被定义为单例。在执行期间,运行时还会尝试重用少量数字和字符串,但最终要在速度和内存之间进行权衡,发生的事情取决于Python运行时的实现方式。
Jochen Ritzel'4


11

虽然两个正确的解决方案x is z,并id(x) == id(z)已经公布,我想指出的Python的实现细节。Python将整数存储为对象,作为一种优化,Python会在其开始处生成一堆小整数(-5到256),并将每个具有小整数的变量指向每个预初始化的对象。更多信息

这意味着对于初始化为相同小数(-5到256)的整数对象,检查两个对象是否相同将返回true(就我所知这是一个实现细节,在ON C-Pyhon上),而对于较大的对象数字,仅当一个对象从另一个对象初始化时,它才返回true。

> i = 13
> j = 13
> i is j
True

> a = 280
> b = 280
> a is b
False

> a = b
> a
280
> a is b
True

python3.6:a = 98765; b = 98765;a是b =>是。某些事情已经明显改变。
Mikhail Kalashnikov

@MikhailKalashnikov没有 我在Python 3.6.2上进行了测试,但这仍然存在。
nix

在python 3.7.7上仍然存在
Bill Huang

9

您还可以使用id()来检查每个变量名称所引用的唯一对象。

In [1]: x1, x2 = 'foo', 'foo'

In [2]: x1 == x2
Out[2]: True

In [3]: id(x1), id(x2)
Out[3]: (4509849040, 4509849040)

In [4]: x2 = 'foobar'[0:3]

In [5]: x2
Out[5]: 'foo'

In [6]: x1 == x2
Out[6]: True

In [7]: x1 is x2
Out[7]: False

In [8]: id(x1), id(x2)
Out[8]: (4509849040, 4526514944)

@ted关于id使用的注释在这里非常相关。
里奥·乌菲姆采夫


2

这来自docs.python.org:“每个对象都有一个标识,一个类型和一个值。创建后,对象的标识就永远不会改变;您可以将其视为对象在内存中的地址。“ is”运算符比较两个对象的标识; id()函数返回一个表示其标识的整数。”

显然,每次更改值时,都会根据标识更改指示重新创建对象。x = 3行,后跟x = 3.14行,没有错误,并且为x提供了不同的标识,类型和值。


1
优秀的文档捕获。
prosti
By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.