鱼C论坛

 找回密码
 立即注册
查看: 1377|回复: 7

[已解决]关于dict和set中的 不可变量 问题 求助!!

[复制链接]
发表于 2018-2-19 09:30:47 | 显示全部楼层 |阅读模式

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

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

x
set 和 dict 与原理都是不可以放入可变量
我在学习的时候 文章举例说明了 可变量和不可变的量的区别
但是我没有读懂
明明用set和dict的量 都可以进行更改 为什么叫不可以变的量?
d = {'Michael': 95, 'Bob': 75, 'Tracy': 85}#这是dict的赋值
d.pop(‘Bob’)#这样的话 这个d变量不就改变了吗
是人为的控制变量的变化吗?
最佳答案
2018-2-19 12:41:43
Auberon 发表于 2018-2-19 11:59
这段代码里 d是一个dict  key是一个list
然后第三行的意思是什么 有点没懂 把 list给d 那‘a list’是什 ...

第三行代码的意思就是,key这这个变量作为d这个字典的一个键,而“a list”是这个键所对应的值。
类似于key是你写的代码中的 ‘Michael’,而‘a list’是 95。
我举这个例子的意思就是当我们把可变量比如列表,作为字典的键时,就会导致值所对应的键不确定。
------------------------------------------------------------分割线-----------------------------------------------------------
你想,dict的原理是数学中的映射,而python为了使dict得查询速度更快,算法复杂度更低,所以使用的就是哈希方法来实现。
而哈希方法是通过键产生一个hash value来进行查找对应的值。所以如果是两个键,那么就会产生两个不同的hash value,那么这两个键所对应的值对象必定是不同的。
反看我们的代码,当我们使用list作为键时,因为list是一个可变量,所以就会因为调用自身方法而改变自身,所以就会改变产生的hash value,就找不到存储的值了。
-----------------------------------------------------分割线-------------------------------------------------------------------
大致说了dict的机制,最后说一下可变量与不可变量。
我们将int、str类型分为不可变对象,而list是可变对象。
说int、str是不可变的,是因为它们调用自身方法,例如字符串调用replace方法,不会改变变量本来的值,而list调用自身方法则会改变。举个例子:
>>> a = 'abc'
>>> a.replace('a', 'A')
'Abc'
>>> a
'abc'
变量a没有发生改变。
>>> a = ['c', 'b', 'a']
>>> a.sort()
>>> a
['a', 'b', 'c']
这个时候变量a作为一个列表,其内部在调用方法后就发生了改变。

而综合前面说的hash方法,如果将list作为键来存储值,而list本身可能会因为调用自身方法而改变,进而导致hash value发生改变,使我们在输入键去找值时,就找不到对应的值了。
所以不能使用list这一类可变对象作为dict的键。而要使用int、str这一类不可变对象作为dict的键。

PS:讲的比较啰嗦,也很粗浅,如果有不对的地方,还请谅解。
想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
回复

使用道具 举报

发表于 2018-2-19 10:08:05 | 显示全部楼层
这里的所说的“不可变量”其实就是指键的值必须是常量,他可以被改变,但不能被指定为一个变量;见下图:
也就是说,字典的值必须是数字,字符串等不可变量。有点拗口,你慢慢体会!
TIM截图20180219100638.bmp
想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
回复 支持 反对

使用道具 举报

发表于 2018-2-19 11:08:51 | 显示全部楼层
dict根据key来计算value的存储位置,如果每次计算相同的key得出的结果不同,那dict就无法得到value的存储位置。
而为了正确的得到value值,作为key的对象就不能变化。而在Python中,字符串、整数等都是不可变的,因此,可以放心地作为key。而list是可变的,就不能作为key。
>>>d = {}
>>>key = [1,2,3]
>>>d[key] = "a list"
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
TypeError: unhashable type: 'list'
所以,不变对象就是那些调用对象自身的任意方法,也不会改变该对象自身的内容。
想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
回复 支持 反对

使用道具 举报

 楼主| 发表于 2018-2-19 11:59:22 | 显示全部楼层
所向故往 发表于 2018-2-19 11:08
dict根据key来计算value的存储位置,如果每次计算相同的key得出的结果不同,那dict就无法得到value的存储位 ...

这段代码里 d是一个dict  key是一个list
然后第三行的意思是什么 有点没懂 把 list给d 那‘a list’是什么意思?
想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
回复 支持 反对

使用道具 举报

 楼主| 发表于 2018-2-19 11:59:53 | 显示全部楼层
铁棍阿童木 发表于 2018-2-19 10:08
这里的所说的“不可变量”其实就是指键的值必须是常量,他可以被改变,但不能被指定为一个变量;见下图:
...

num1;num2;num3;都是变量吗?
想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
回复 支持 反对

使用道具 举报

发表于 2018-2-19 12:28:06 | 显示全部楼层
不可变量指的是像整型,字符串,元组这样的,他们在创建的时候分配了一个地址,如果你改变了他,例如把“你好”改成“你好啊”,他本质上是创建了一个新的字符串,并不是在原有的字符串上追加,但是可变量的列表,你给他append了一个元素,他本身地址并没有发生改变,列表还是同一个列表,只是添加了一个元素进去。具体的思路你可以看看浅拷贝和深拷贝
想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
回复 支持 反对

使用道具 举报

发表于 2018-2-19 12:41:43 | 显示全部楼层    本楼为最佳答案   
Auberon 发表于 2018-2-19 11:59
这段代码里 d是一个dict  key是一个list
然后第三行的意思是什么 有点没懂 把 list给d 那‘a list’是什 ...

第三行代码的意思就是,key这这个变量作为d这个字典的一个键,而“a list”是这个键所对应的值。
类似于key是你写的代码中的 ‘Michael’,而‘a list’是 95。
我举这个例子的意思就是当我们把可变量比如列表,作为字典的键时,就会导致值所对应的键不确定。
------------------------------------------------------------分割线-----------------------------------------------------------
你想,dict的原理是数学中的映射,而python为了使dict得查询速度更快,算法复杂度更低,所以使用的就是哈希方法来实现。
而哈希方法是通过键产生一个hash value来进行查找对应的值。所以如果是两个键,那么就会产生两个不同的hash value,那么这两个键所对应的值对象必定是不同的。
反看我们的代码,当我们使用list作为键时,因为list是一个可变量,所以就会因为调用自身方法而改变自身,所以就会改变产生的hash value,就找不到存储的值了。
-----------------------------------------------------分割线-------------------------------------------------------------------
大致说了dict的机制,最后说一下可变量与不可变量。
我们将int、str类型分为不可变对象,而list是可变对象。
说int、str是不可变的,是因为它们调用自身方法,例如字符串调用replace方法,不会改变变量本来的值,而list调用自身方法则会改变。举个例子:
>>> a = 'abc'
>>> a.replace('a', 'A')
'Abc'
>>> a
'abc'
变量a没有发生改变。
>>> a = ['c', 'b', 'a']
>>> a.sort()
>>> a
['a', 'b', 'c']
这个时候变量a作为一个列表,其内部在调用方法后就发生了改变。

而综合前面说的hash方法,如果将list作为键来存储值,而list本身可能会因为调用自身方法而改变,进而导致hash value发生改变,使我们在输入键去找值时,就找不到对应的值了。
所以不能使用list这一类可变对象作为dict的键。而要使用int、str这一类不可变对象作为dict的键。

PS:讲的比较啰嗦,也很粗浅,如果有不对的地方,还请谅解。
想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
回复 支持 反对

使用道具 举报

 楼主| 发表于 2018-2-19 12:47:34 | 显示全部楼层
所向故往 发表于 2018-2-19 12:41
第三行代码的意思就是,key这这个变量作为d这个字典的一个键,而“a list”是这个键所对应的值。
类似于 ...

懂了 谢谢你 打这么多字讲解 万分感谢!
想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
回复 支持 反对

使用道具 举报

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

本版积分规则

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

GMT+8, 2024-12-23 18:19

Powered by Discuz! X3.4

© 2001-2023 Discuz! Team.

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