Python的'is'操作符用于比较两个字符串切片

190
4
跳到解决方案
11-15-2022上午12:15
MubashshirHasan
新贡献者II

我在Python中尝试字符串切片,这是我想到的代码:

s = '字符串' print (id (s[3:]),身份证(s[5:]))打印(id (s [3:]) = = id (s[5:]))打印(s [3:] s[5:])打印(s [3:] [3:])

以下是代码的结果:

4396519216 4396519216真假假

网站提供了各种实例,但我不确定它们是什么意思。我的问题是这些字符串切片是如何存储在内存中,为什么一个字符串的不同切片具有相同的id,以及为什么与使用具有相同id的'is'关键字相比,它们会产生'False'。

标签(2)
0荣誉
1解决方案

接受的解决方案
DanPatterson
通过 尊敬的贡献者
尊敬的贡献者

多次运行相同的id检查,看看它返回什么

返回对象的标识。这保证在同时存在的对象中是唯一的。#(CPython使用对象的内存地址)s = 'a string' id(s[:3]) # 2625512614384 id(s[:3]) # 2625512614000 id(s[:3]) # 2625512614000 id(s[:3]) # 2625512908528 # id(s[:3]) is id(s[:3]) # False # id(id(s[:3]) == id(s[:3])) # 140711459289192 id(s[:3] == s[:3]) # 140711459289192 id(s[:3]) # 140711459289192

现在,把你的头绕到最后两行。


...有点退休了…

在原帖子中查看解决方案

4回复
DanPatterson
通过 尊敬的贡献者
尊敬的贡献者

多次运行相同的id检查,看看它返回什么

返回对象的标识。这保证在同时存在的对象中是唯一的。#(CPython使用对象的内存地址)s = 'a string' id(s[:3]) # 2625512614384 id(s[:3]) # 2625512614000 id(s[:3]) # 2625512614000 id(s[:3]) # 2625512908528 # id(s[:3]) is id(s[:3]) # False # id(id(s[:3]) == id(s[:3])) # 140711459289192 id(s[:3] == s[:3]) # 140711459289192 id(s[:3]) # 140711459289192

现在,把你的头绕到最后两行。


...有点退休了…
RogerDunnGIS
通过
偶然的因素

我已经做了很多年的ArcGIS Python程序员,我从来没有真正需要id()函数或is操作符来完成实际工作。实际上,我只关心相等(==)。既然你只是在尝试,我想这就足够了,但这可能不是一个你不需要深入研究的兔子洞。

这就是上面代码中发生的事情。

打印语句调用时使用逗号,这意味着每个参数#将被计算,从左到右一次一个。# 2) s[3:]生成一个带有id的新字符串# 3)该字符串传递给id函数,返回它的内存地址# 4)该内存地址进入一个新的int对象# 5)该字符串不再需要,因此被释放# 6)s[5:]生成一个新的字符串,重用空闲内存# 7)该字符串传递给id函数,返回它的内存地址#: smiling_face_with_sunglasses:# 9)不再需要该字符串,因此释放该字符串。#两个对象在存活时具有相同的id,因此打印出#相同的id。print(id(s[3:]), id(s[5:])) #与上面类似,每个参数从左到右计算。这一次,print只有一个参数,但是参数#是一个运算符的结果。运算符从左到右解析它的操作数#。#执行步骤1到9,注意4)和8)。# Int对象如果具有相同的值,则它们彼此相等,因此将True返回到print语句。print(id(s[3:])==id(s[5:])) # 1) print语句被调用时带有一个形参,由#它没有逗号可以证明# 2)print语句唯一的形参是is操作符的结果# 3)is操作符从左到右计算其操作数# 4)s[3:]生成一个带有id的新字符串#注意,is操作符仍然需要这个新字符串,因此没有释放它#。它挂在内存# 6)s[5:]生成一个带有id的新字符串# is操作符也需要这个新字符串,所以它也没有被释放# 7)is操作符现在比较两个活字符串的标识,#看到它们不相等,并在两个实例中返回False。打印(s[3:]是s[5:]) (s[3:]是s[3:])

现在,来谈谈@DanPatterson职位:

s = 'a string' #由于没有打印语句,我不确定他是如何在评论中得到结果的。也许,如果在终端中运行,或者在不同的#时间,新的字符串没有重用最近释放的内存。id(s) # 2625510363760 id(s[:3]) # 2625512614384 id(s[:3]) # 2625512614000 id(s[:3]) # 2625512908528 # 1) is操作符从左到右计算其操作数# 2)s[:3]创建一个带有id的新字符串# 3)id函数被调用,返回一个新的int对象# 4)释放新字符串,释放其内存# 5)s[:3]创建一个带有id的新字符串。6)调用id函数,返回一个新的int对象# 7)is操作符尝试在返回的#两个尚未释放的int对象上建立标识。# int是不同的对象,所以is返回False。id(s[:3]) is id(s[:3]) # False #这实际上是最容易解释的。Dan可以使用#键入id(10>7), id(" PYTHON".lower()中的"h"),或id(5!=7) #,并且仍然获得相同的内存地址。他所做的是获取操作符的结果id。这些结果是愚蠢的。值# True和False是bool类型的全局对象。 Because # they are objects, they each have an id. Comparator operators # don't create new instances of type bool, but simply # use the existing ones. id(id(s[:3]) == id(s[:3])) # 140711459289192 id(s[:3] == s[:3]) # 140711459289192
DanPatterson
通过 尊敬的贡献者
尊敬的贡献者

就像我说的,还有自学的解释: thinking_face:


...有点退休了…
RogerDunnGIS
通过
偶然的因素

下面是另一个练习:

在这里,我们创建了一个元组,其中包含两个新字符串作为切片操作的结果。由于两个字符串都保留在内存中,#都不会被释放,它们的id也会不同。Orange_slices = (s[:3], s[:5]) id(Orange_slices [0]) 1448227048496 id(Orange_slices [1]) 1448234245616
0荣誉