从最近的一个这样的问题(参见在python中创建一个由列表索引的字典)中,我意识到我可能对python中的可理解和不可变对象的含义有了错误的理解。
发布于 2016-08-07 09:24:36
在Python中,元组是不可变的,但只有当它的所有元素都是hashable时,元组才是可选的。
>>> tt = (1, 2, (30, 40))
>>> hash(tt)
8027212646858338501
>>> tl = (1, 2, [30, 40])
>>> hash(tl)
TypeError: unhashable type: 'list'可选类型
发布于 2010-04-19 23:02:05
来自Python词汇
如果一个对象的哈希值在其生存期内从未改变(它需要一个
__hash__()方法),并且可以与其他对象(它需要一个__eq__()或__cmp__()方法)进行比较,那么它是可选的。比较相等的可访问对象必须具有相同的哈希值。 Hashability使对象可以作为字典键和集合成员使用,因为这些数据结构在内部使用哈希值。 Python的所有不可变的内置对象都是可选的,而没有可变的容器(如列表或字典)。对象是用户定义类的实例,默认情况下是可选的;它们都比较不平等,它们的哈希值是它们的id()。
Dicts和set必须使用哈希在哈希表中进行有效查找;哈希值必须是不可变的,因为更改哈希将扰乱数据结构并导致dict或set失败。使哈希值不可变的最简单方法是使整个对象不可变,这就是为什么经常将两者放在一起。
虽然内置的可变对象中没有一个是可选的,但是可以使用不可变的哈希值生成一个可变的对象。只有一部分对象表示其标识是常见的,而对象的其余部分则包含可以自由更改的属性。只要哈希值和比较函数是基于标识而不是基于可变属性,并且标识永不更改,您就满足了这些要求。
发布于 2010-04-19 22:41:03
从技术上讲,hashable意味着类定义了__hash__()。根据医生的说法:
__hash__()应该返回一个整数。唯一需要的属性是,比较相等的对象具有相同的散列值;建议以某种方式将对象的组件的散列值混合在一起(例如使用排它值或散列值),这些散列值在对象的比较中也起着作用。
我认为对于Python内置类型,所有的hashable类型也是不可变的。
要有一个定义__hash__()的可变对象是困难的,但也可能不是不可能的。
https://stackoverflow.com/questions/2671376
复制相似问题