鱼C论坛

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

python 可变对象和不可变对象

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

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

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

x

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

2.dict的key必须是不可变对象,哪些是不可变对象?
想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
回复

使用道具 举报

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

使用道具 举报

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

使用道具 举报

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

你说的不可变集合是只set?
想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
回复 支持 反对

使用道具 举报

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

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

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

使用道具 举报

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

set不能放入可变对象,但是本身又有增加,删除操作,为什么,这两者有关系吗?
想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
回复 支持 反对

使用道具 举报

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

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

不可变不是应该是内容改变了但是内存地址不改变吗?
>>> a=3
>>> id(a)
500586800
>>> a=5
>>> id(a)
500586832  #改变值后地址也变了---不可变变量
>>> b=[2,3]
>>> id(b)
53227848
>>> b[1]=5
>>> id(b)
53227848 #改变值后地址不变---可变变量


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

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


>>> b
(3, 4) #b的第0个元素仍然是3
>>> c=[2]
>>> b=(c,0)
>>> b
([2], 0)
>>> c.append(3) #c的地址没变
>>> b
([2, 3], 0) #所以b的第0个元素也跟着改变了。
想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
回复 支持 反对

使用道具 举报

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

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

使用道具 举报

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

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

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

可变是因为内容变了,比如简单类型,内容变了,内存地址也变了,但是也有可能内容变了,地址不变的,例如list
想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
回复 支持 反对

使用道具 举报

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

是这样的对于容器型变量本身有地址,每个元素还有它的地址。
想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
回复 支持 反对

使用道具 举报

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

简单类别的数据,a=9,这样的有内存地址吗
想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
回复 支持 反对

使用道具 举报

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

有呀。
>>> a=9
>>> id(a)
500586896
想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
回复 支持 反对

使用道具 举报

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

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

使用道具 举报

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

还是简单类型:比如整型,如果同一个变量a重新赋值了 ...
>>> a=[1,2,3]
>>> id(a)
49790216
>>> id([1,2,3])
49790728
>>> a=66#引向新的值,变了
>>> id(a)#变了
1526709344
>>> id([1,2,3])#列表也变了
49954568
>>> a=(1,2,3)#令为元组
>>> id(a)
50144456
>>> id((1,2,3))
50074824
>>> a=66
>>> id(a)#引向新的值,变了
1526709344
>>> id((1,2,3))#元组的不变
50074824
由上面可知,变的是对象自身,变量并没有变,列表可变所以变了,元组不可变所以没变。
其实注意看,两次a等于常量66时,a的id都是一样的,也就是当变量改变引向对象时,之前那个对象其实并没有消失,而是存在了内存里,再次使用时又出现,并且常量也是不可变的
想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
回复 支持 反对

使用道具 举报

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

本版积分规则

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

GMT+8, 2025-2-23 20:16

Powered by Discuz! X3.4

© 2001-2023 Discuz! Team.

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