对可变对象的疑虑点,请廖大佬指点迷津,多谢!
Topic sourcedict拒绝list作为key不是因为list是可变,而是dict要求任何key对象都必须实现__hash__
实现了__hash__
即使是可变的也可以作为dict的key,但是一个对象的__hash__
必须始终保证返回的值不能变,如果变了,就会导致dict工作不正常。
懂了懂了,多谢廖大佬。^_^
也就是说,
list
里面的值其实只要满足不可变的特性就行了。- 而
dict
对key
的要求是可__hash__
,而且同一个key
的__hash__
的结果必须相同,那么是不是key
在极端情况下写一个可变对象也行,只要这个对象的__hash__
每次都能给一个不变的固定值就可以了。
还有,
tuple
里面用的是相关对象的地址
,这是语言设计本身的特性,就是这样设计的,哪怕里面是简单的字符a
,那也是用的a
的地址
。- 而
dict
的key
用的是真真切切的对象的值
,而不是对象的地址
,且要求此对象值可__hash__
并__hash__
值不可变。
廖大佬,以上是我的理解,不正确还望不吝斧正,多谢了!
dict的原理你看JDK的HashMap就明白了
根据key查找的逻辑:
给出一个key,先计算hashCode(),这样可以直接定位到0个(没找到)、1个或多个(hash碰撞)value,然后,根据equals()依次比较key,返回对应的value
dict的原理决定了作为key的对象hash不能变,不然用"abc"放进去的value再用"abc"就查不出来了。两个不同的对象,如果逻辑上相等,必须hash相等,因为你用来查找的key不一定就是你放进去的key:
originalKey = Student('Bob')
aDict[originalKey] = 'ok'
anotherKey = Student('Bob') # 新对象
value = aDict[anotherKey] # 'ok'
- 1
LHYNGU
对可变对象的疑虑点,请廖大佬指点迷津,多谢!
问题描述:
元组
tuple
的元素只能容纳不可变对象,且其中的元素可以是列表list
,因为实际存放的是列表(可变对象)的地址,只要这个可变列表的地址不变,就算列表中的元素变化了,也不能说是元组元素的变动。字典
dict
的key不能是可变元素,因为需要用key去hash取值。如果此时key为列表(可变对象),则字典会报错:TypeError: unhashable type: 'list'
。那么问题来了: 同样是可变元素
list
,为什么在元组tuple
里面作为元素值是合法的、是取地址
的、是不可变的,但是在字典dict
里面作为key的值就是非法的、是取值
的、是可变的。这样的设计,感觉不符合使用上的一致性或直观的理解性吧,因为规则不一致。