在Python中使用'is'运算符比较两个字符串片段。

4

我正在使用Python进行字符串切片实验,这是我的代码:

s = 'a string'
print(id(s[3:]), id(s[5:]))
print(id(s[3:])==id(s[5:]))
print(s[3:] is s[5:])
print(s[3:] is s[3:])

代码产生了以下结果:
4396519216 4396519216
True
False
False

我的问题是这些字符串切片是如何存储在内存中的?为什么同一个字符串的不同切片具有相同的id,而使用相同的id进行比较时,它们会使用'is'关键字产生'False'?

2个回答

9
由于在调用 id 后没有将切片保存在变量(或任何地方),它们的生命周期实际上是不重叠的,因此id 可能会被重复使用。
根据id() 的文档

返回对象的“标识”。这是一个整数,保证在对象的生命周期内唯一且恒定。两个生命周期不重叠的对象可能具有相同的 id() 值。

请注意,因为 is 需要它们同时存在,所以它们可能会获得不同的 id,但是当您单独对每个对象调用 id 时,它可以在id 返回后被销毁,并且比较本身是基于从函数返回的 int 进行的。
如果将它们保存到虚拟变量中,我认为结果会更少令人惊讶:
s = 'a string'
s3 = s[3:]
s5 = s[5:]
print(id(s3), id(s5))
print(id(s3)==id(s5))
print(s3 is s5)
print(s3 is s3)

输出:

25517664 25517728
False
False
True

1
"

==语法用于比较字符串对象的值,实际上是在String对象上运行__eq__方法。

is语法用于比较对象本身,而不是对象的值。当您切片一个字符串时,您正在创建一个新对象。

"
>>> print(id(s[3:]))
139911809265200
>>> print(id(s[3:]))
139911809262384

我不理解从id函数返回的值发生了奇怪的事情。但是,这个id问题是一个独立的问题,不会影响==is语法的工作方式。

>>> (id(s[3:]), id(s[3:]), id(s[3:]), id(s[3:]))
(139911809265200, 139911809265200, 139911809265200, 139911809265200)
>>> (id(s[3:]), id(s[3:]), id(s[3:]), id(s[3:]))
(139911809262384, 139911809262384, 139911809262384, 139911809262384)
>>> (id(s[3:]), id(s[3:]), id(s[3:]), id(s[3:]))
(139911809265200, 139911809265200, 139911809265200, 139911809265200)
>>> (id(s[3:]), id(s[3:]), id(s[3:]), id(s[3:]))
(139911809262384, 139911809262384, 139911809262384, 139911809262384)

>>> a = id(s[3:])
>>> id(a)
139911809261520
>>> b = id(s[3:])
>>> id(b)
139911809261424
>>> c = id(s[3:])
>>> id(c)
139911809261360


>>> (id(a), id(b), id(c))
(139911809261520, 139911809261424, 139911809261360)
>>> (id(a), id(b), id(c))
(139911809261520, 139911809261424, 139911809261360)
>>> (id(s[3:]), id(s[3:]), id(s[3:]))
(139911809265200, 139911809265200, 139911809265200)
>>> (id(s[3:]), id(s[3:]), id(s[3:]))
(139911809263472, 139911809263472, 139911809263472)
>>> (id(s[3:]), id(s[3:]), id(s[3:]))
(139911809265200, 139911809265200, 139911809265200)


感谢您进行后续实验。我相信这种行为与Python如何在内存中创建和存储字符串切片有关,但我仍然对此细节一无所知。 - zvzv1919

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接