微信公众号搜"智元新知"关注
微信扫一扫可直接关注哦!

为什么集合不能存储可变数据类型?

如何解决为什么集合不能存储可变数据类型?

我在一本书中读到,由于“算法基础”,只能将不可变类型的实例添加到 Python set,但它没有解释什么是“算法基础”。

在尝试实际添加要设置的列表(可变数据类型)后,我收到一条错误消息,提示 TypeError: unhashable type: list,但为什么要添加的项目必须是可散列的?

>>> my_set = set()
>>> my_set.add('a')
>>> my_set.add(1)
>>> my_set.add((1,2,3))
>>> my_set.add([1,3])
Traceback (most recent call last):
  File "<stdin>",line 1,in <module>
TypeError: unhashable type: 'list'

解决方法

来自Python documentation

集合对象是不同的可散列对象的无序集合

如果一个对象的哈希值在其生命周期内永远不会改变(它需要一个 __hash__() 方法),并且可以与其他对象进行比较(它需要一个 __eq__() 方法),那么它就是可散列的。比较相等的可散列对象必须具有相同的散列值。

为了解释这意味着什么,集合/字典基于哈希表的概念,其中所有的键不是用它们的实际值存储,而是用它们的哈希存储。散列是从键值计算出来的整数。

例如,如果我想将键 k="Hello" 插入具有散列函数 f(k) = sum of all ASCII values 的集合中,那么您将获得 Hash of k = f(k) = 72+101+108+108+111 = 500,并且您将存储 k在位置 500 (当然比这个复杂很多,只是个蠢例子)。

这样当你想检查 k 是否在集合中时,你不必做线性搜索,但你可以计算它的散列并在索引 500 处检查是否有东西,所以它是快多了。 (这就是为什么当集合有很多元素时,集合比列表快得多)。

小问题:如果你的键是一个列表,你可以修改它,这会改变它的散列,所以每次修改列表时,你需要编辑包含它的所有集合/字典,它会是一团糟,所以最好避免可变类型,这就是列表不可散列的原因。

版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 dio@foxmail.com 举报,一经查实,本站将立刻删除。