鱼C论坛

 找回密码
 立即注册
查看: 1831|回复: 8

[已解决]id()函数相同不同问题

[复制链接]
发表于 2022-3-11 21:43:03 | 显示全部楼层 |阅读模式

马上注册,结交更多好友,享用更多功能^_^

您需要 登录 才可以下载或查看,没有账号?立即注册

x
0.
>>> s = [3,1]
>>> id(s)
1924965623360
>>> s *= 2
>>> id(s)
1924965623360
>>> s
[3, 1, 3, 1]
>>> s = [3,1,3,1]
>>> id(s)
1924965974720
前两个id一样我能理解,可变序列是在原位置修改 “扩容”,但是当我手动再次输入相同值的列表s为什么id却不同了?
1.
>>> s = [1]
>>> id(s)
1924965623296
>>> s=[1]
>>> id(s)
1924930235328
第一个s列表赋值加空格,第二个没加空格,输出的id为啥会不一样呢?
2.
>>> s = [1]
>>> id(s)
1924930235328
>>> s[1:2] = [2]
>>> s
[1, 2]
>>> id(s)
1924930235328
>>> s[1:] = [3]
>>> s
[1, 3]
>>> id(s)
1924930235328
对s用切片和语法不改变id,但是用+(拼接)却改变了
>>> s.append(4)
>>> s
[1, 3, 4]
>>> id(s)
1924930235328
>>> s = s+[5]
>>> s
[1, 3, 4, 5]
>>> id(s)
1924965327808
综上,请问各位前辈,作为字符的身份证(唯一标识id),什么情况id可变,什么情况id不变。感谢各位前辈指点。
最佳答案
2022-3-11 22:05:01
本帖最后由 isdkz 于 2022-3-11 22:07 编辑

在 python 中 id 用于标识变量的地址,改变了变量的指向,地址变了 id 自然跟着变,

改变变量的指向的操作即赋值操作,所以对原来的变量重新赋值 id 就会变,没有对原来的变量重新赋值 id 就不变,

这里有一个挺有意思的就是对于可变对象来说 a += b 并不等同于 a = a + b,
>>> a = [1, 2, 3]
>>> id(a)
2585549852480
>>> a = a + [4]
>>> id(a)                   # 地址变了
2585549898176
>>> a += [5]
>>> id(a)                   # 地址还是跟上次的地址一样,没有发生变化
2585549898176
>>>


所以在可变对象中 += 也是对原来的内存进行操作,不会导致 id 发生变化
小甲鱼最新课程 -> https://ilovefishc.com
回复

使用道具 举报

发表于 2022-3-11 21:50:30 From FishC Mobile | 显示全部楼层
可变容器类例如列表集合字典,请将他们的地址理解为水缸,新增或者删减元素只是往水缸里添水或者从水缸倒水,而重新的赋值是另外的水缸,跟原来的不同。请理解为,只要在原水缸操作,那么ID就相同,只要经过重新赋值那么ID就不再是原来的地址,这一点和字符串数字之类完全不同。
小甲鱼最新课程 -> https://ilovefishc.com
回复 支持 反对

使用道具 举报

发表于 2022-3-11 22:05:01 | 显示全部楼层    本楼为最佳答案   
本帖最后由 isdkz 于 2022-3-11 22:07 编辑

在 python 中 id 用于标识变量的地址,改变了变量的指向,地址变了 id 自然跟着变,

改变变量的指向的操作即赋值操作,所以对原来的变量重新赋值 id 就会变,没有对原来的变量重新赋值 id 就不变,

这里有一个挺有意思的就是对于可变对象来说 a += b 并不等同于 a = a + b,
>>> a = [1, 2, 3]
>>> id(a)
2585549852480
>>> a = a + [4]
>>> id(a)                   # 地址变了
2585549898176
>>> a += [5]
>>> id(a)                   # 地址还是跟上次的地址一样,没有发生变化
2585549898176
>>>


所以在可变对象中 += 也是对原来的内存进行操作,不会导致 id 发生变化
小甲鱼最新课程 -> https://ilovefishc.com
回复 支持 反对

使用道具 举报

 楼主| 发表于 2022-3-11 22:41:13 | 显示全部楼层
qq1151985918 发表于 2022-3-11 21:50
可变容器类例如列表集合字典,请将他们的地址理解为水缸,新增或者删减元素只是往水缸里添水或者从水缸倒水 ...

s=[1]和s = [1]不同是因为重新赋值么?
那么s = s+[5]和s不同也是因为重新赋值么?不能理解为往原水缸里面加水么?
感谢指教,受益匪浅,
小甲鱼最新课程 -> https://ilovefishc.com
回复 支持 反对

使用道具 举报

发表于 2022-3-11 22:43:16 | 显示全部楼层
你手上有2个苹果,这2个苹果是一个吗?
小甲鱼最新课程 -> https://ilovefishc.com
回复 支持 1 反对 0

使用道具 举报

 楼主| 发表于 2022-3-11 22:47:33 | 显示全部楼层
isdkz 发表于 2022-3-11 22:05
在 python 中 id 用于标识变量的地址,改变了变量的指向,地址变了 id 自然跟着变,

改变变量的指向的操 ...

这是不是就解释了
x = [1]
y = [1]
x is y
False
因为可变序列赋值就会指向新的地址,而不可变序列返回结果就是True指向原来的地址。
好神奇啊,那么这样看来以后做自身加法运算最好用a+=b,这样直接能够在源地址更改,
比新建立个地址更能提高效率。
小甲鱼最新课程 -> https://ilovefishc.com
回复 支持 反对

使用道具 举报

发表于 2022-3-11 23:14:12 | 显示全部楼层
李二蛋 发表于 2022-3-11 22:47
这是不是就解释了
x = [1]
y = [1]


只要重新赋值地址就会发生改变(除了常量池里面的值,这个你了解一下就好,如果你对某个变量重新赋值发现它的地址没变,你可以去查一下 python常量池 的内容),

因为赋值操作就是将变量指向值所在的地址的操作,

所以只要重新赋值就会发生地址变化,而对于可变对象来说,+= 并没有改变变量的指向,

要说效率对于计算机来说也差不了多少,就是不需要回收旧的地址
小甲鱼最新课程 -> https://ilovefishc.com
回复 支持 反对

使用道具 举报

发表于 2022-3-11 23:48:18 From FishC Mobile | 显示全部楼层
李二蛋 发表于 2022-3-11 22:41
s=[1]和s = [1]不同是因为重新赋值么?
那么s = s+[5]和s不同也是因为重新赋值么?不能理解为往原水缸里 ...

是的,重新赋值就是新的变量,id指向就会变化。当然我是说可变容器类,如果是数字和字符串,那是不同的。
小甲鱼最新课程 -> https://ilovefishc.com
回复 支持 1 反对 0

使用道具 举报

 楼主| 发表于 2022-3-16 14:45:13 | 显示全部楼层
ba21 发表于 2022-3-11 22:43
你手上有2个苹果,这2个苹果是一个吗?

牛逼,一刀见血
小甲鱼最新课程 -> https://ilovefishc.com
回复 支持 反对

使用道具 举报

您需要登录后才可以回帖 登录 | 立即注册

本版积分规则

小黑屋|手机版|Archiver|鱼C工作室 ( 粤ICP备18085999号-1 | 粤公网安备 44051102000585号)

GMT+8, 2025-6-20 19:04

Powered by Discuz! X3.4

© 2001-2023 Discuz! Team.

快速回复 返回顶部 返回列表