鱼C论坛

 找回密码
 立即注册
查看: 3531|回复: 13

python 可变对象和不可变对象

[复制链接]
发表于 2017-7-28 14:44:41 | 显示全部楼层 |阅读模式

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

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

x

1.python 可变对象和不可变对象怎么理解?

2.dict的key必须是不可变对象,哪些是不可变对象?
小甲鱼最新课程 -> https://ilovefishc.com
回复

使用道具 举报

发表于 2017-7-28 14:55:54 | 显示全部楼层
不可变对象就是一旦创建好就不能改变的对象,比如 ,字符串,元祖,不可变集合.常量等,除此之外都是可变的,典型代表是列表,
小甲鱼最新课程 -> https://ilovefishc.com
回复 支持 反对

使用道具 举报

发表于 2017-7-28 14:59:33 | 显示全部楼层
简单的说,可变是指在原来的内存地址直接改变,不可变是指内容改变时存储的地址也变了。
因为python的变量名是一个标签,如果它指向的数字发生变化称为可变,如果这种变化需要指向新的地址就称为不可变。
不可变对象包括:所有简单类型,如整数、浮点数、字符串,也有容器型,如元组。
可变的有列表、字典、集合等。
小甲鱼最新课程 -> https://ilovefishc.com
回复 支持 反对

使用道具 举报

 楼主| 发表于 2017-7-28 15:15:31 | 显示全部楼层
Krant5 发表于 2017-7-28 14:55
不可变对象就是一旦创建好就不能改变的对象,比如 ,字符串,元祖,不可变集合.常量等,除此之外都是可变的,典型 ...

你说的不可变集合是只set?
小甲鱼最新课程 -> https://ilovefishc.com
回复 支持 反对

使用道具 举报

 楼主| 发表于 2017-7-28 15:19:31 | 显示全部楼层
冬雪雪冬 发表于 2017-7-28 14:59
简单的说,可变是指在原来的内存地址直接改变,不可变是指内容改变时存储的地址也变了。
因为python的变量 ...

不可变不是应该是内容改变了但是内存地址不改变吗?

还是简单类型:比如整型,如果同一个变量a重新赋值了,内容是变了,但是元组中存放的是这个变量名a,那元组的内容不是应该是变量a变化后的值?
小甲鱼最新课程 -> https://ilovefishc.com
回复 支持 反对

使用道具 举报

 楼主| 发表于 2017-7-28 15:24:59 | 显示全部楼层
冬雪雪冬 发表于 2017-7-28 14:59
简单的说,可变是指在原来的内存地址直接改变,不可变是指内容改变时存储的地址也变了。
因为python的变量 ...

set不能放入可变对象,但是本身又有增加,删除操作,为什么,这两者有关系吗?
小甲鱼最新课程 -> https://ilovefishc.com
回复 支持 反对

使用道具 举报

发表于 2017-7-28 15:30:35 | 显示全部楼层
只为 发表于 2017-7-28 15:19
不可变不是应该是内容改变了但是内存地址不改变吗?

还是简单类型:比如整型,如果同一个变量a重新赋值了 ...

不可变不是应该是内容改变了但是内存地址不改变吗?
  1. >>> a=3
  2. >>> id(a)
  3. 500586800
  4. >>> a=5
  5. >>> id(a)
  6. 500586832  #改变值后地址也变了---不可变变量
  7. >>> b=[2,3]
  8. >>> id(b)
  9. 53227848
  10. >>> b[1]=5
  11. >>> id(b)
  12. 53227848 #改变值后地址不变---可变变量
复制代码



还是简单类型:比如整型,如果同一个变量a重新赋值了,内容是变了,但是元组中存放的是这个变量名a,那元组的内容不是应该是变量a变化后的值?

元组存放的不是这个变量,而是变量的地址,当变量重新赋值后,地址改变了,但元组中元素仍指向原来的地址,即,元组的内容不是变量a变化后的值。你体会一下下面的代码。
  1. >>> a=3
  2. >>> b=(a,4)
  3. >>> b
  4. (3, 4)
  5. >>> a=4


  6. >>> b
  7. (3, 4) #b的第0个元素仍然是3
  8. >>> c=[2]
  9. >>> b=(c,0)
  10. >>> b
  11. ([2], 0)
  12. >>> c.append(3) #c的地址没变
  13. >>> b
  14. ([2, 3], 0) #所以b的第0个元素也跟着改变了。
复制代码
小甲鱼最新课程 -> https://ilovefishc.com
回复 支持 反对

使用道具 举报

发表于 2017-7-28 15:38:41 | 显示全部楼层
只为 发表于 2017-7-28 15:24
set不能放入可变对象,但是本身又有增加,删除操作,为什么,这两者有关系吗?

我想是这样的:
set中是没有重复元素的,当set中元素都是不可变变量,当某个值改变,必将使其地址改变,引发set判断是否是重复元素;而如果其元素是可变变量,其改变值,地址不变,set就不容易判断,或者说set必须随时判断其中元素值的变化,这必将大大降低工作效率。
另set是以hash散列存储的,是否有这个原因我不太清楚。
小甲鱼最新课程 -> https://ilovefishc.com
回复 支持 反对

使用道具 举报

 楼主| 发表于 2017-7-28 15:45:19 | 显示全部楼层
冬雪雪冬 发表于 2017-7-28 14:59
简单的说,可变是指在原来的内存地址直接改变,不可变是指内容改变时存储的地址也变了。
因为python的变量 ...

简单的说,可变是指在原来的内存地址直接改变,不可变是指内容改变时存储的地址也变了。

上面这句话的理解是:实际可变或者不可变针对的是值,是内容,不是内存地址.不可变是内容不变,如果内容改变了,内存地址也改变了.(有点绝对,元组的元素如果是list就不对了)

可变是因为内容变了,比如简单类型,内容变了,内存地址也变了,但是也有可能内容变了,地址不变的,例如list
小甲鱼最新课程 -> https://ilovefishc.com
回复 支持 反对

使用道具 举报

发表于 2017-7-28 15:55:47 | 显示全部楼层
上面这句话的理解是:实际可变或者不可变针对的是值,是内容,不是内存地址.不可变是内容不变,如果内容改变了,内存地址也改变了.(有点绝对,元组的元素如果是list就不对了)

是这样的对于容器型变量本身有地址,每个元素还有它的地址。
小甲鱼最新课程 -> https://ilovefishc.com
回复 支持 反对

使用道具 举报

 楼主| 发表于 2017-7-28 16:12:16 | 显示全部楼层
冬雪雪冬 发表于 2017-7-28 15:55
上面这句话的理解是:实际可变或者不可变针对的是值,是内容,不是内存地址.不可变是内容不变,如果内容改变了, ...

简单类别的数据,a=9,这样的有内存地址吗
小甲鱼最新课程 -> https://ilovefishc.com
回复 支持 反对

使用道具 举报

发表于 2017-7-28 16:14:34 | 显示全部楼层
只为 发表于 2017-7-28 16:12
简单类别的数据,a=9,这样的有内存地址吗

有呀。
  1. >>> a=9
  2. >>> id(a)
  3. 500586896
复制代码
小甲鱼最新课程 -> https://ilovefishc.com
回复 支持 反对

使用道具 举报

发表于 2017-7-31 17:54:51 | 显示全部楼层
Krant5 发表于 2017-7-28 14:55
不可变对象就是一旦创建好就不能改变的对象,比如 ,字符串,元祖,不可变集合.常量等,除此之外都是可变的,典型 ...

变量只是贴的标签,变量本身是不可变的(难道变量a还能变成b?),可变不可变在于变量指向的对象而定,如果指向的是列表,字典就是可变的,如果指向的字符串,元组就是不可变的
小甲鱼最新课程 -> https://ilovefishc.com
回复 支持 反对

使用道具 举报

发表于 2017-7-31 18:08:36 | 显示全部楼层
只为 发表于 2017-7-28 15:19
不可变不是应该是内容改变了但是内存地址不改变吗?

还是简单类型:比如整型,如果同一个变量a重新赋值了 ...
  1. >>> a=[1,2,3]
  2. >>> id(a)
  3. 49790216
  4. >>> id([1,2,3])
  5. 49790728
  6. >>> a=66#引向新的值,变了
  7. >>> id(a)#变了
  8. 1526709344
  9. >>> id([1,2,3])#列表也变了
  10. 49954568
  11. >>> a=(1,2,3)#令为元组
  12. >>> id(a)
  13. 50144456
  14. >>> id((1,2,3))
  15. 50074824
  16. >>> a=66
  17. >>> id(a)#引向新的值,变了
  18. 1526709344
  19. >>> id((1,2,3))#元组的不变
  20. 50074824
复制代码

由上面可知,变的是对象自身,变量并没有变,列表可变所以变了,元组不可变所以没变。
其实注意看,两次a等于常量66时,a的id都是一样的,也就是当变量改变引向对象时,之前那个对象其实并没有消失,而是存在了内存里,再次使用时又出现,并且常量也是不可变的
小甲鱼最新课程 -> https://ilovefishc.com
回复 支持 反对

使用道具 举报

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

本版积分规则

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

GMT+8, 2025-12-22 15:46

Powered by Discuz! X3.4

© 2001-2023 Discuz! Team.

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