Python 中 TypeError: unhashable type: 'set' 错误
当我们将一个集合用作字典中的键或另一个集合中的元素时,会出现 Python“TypeError: unhashable type: 'set' ”。 要解决该错误,请改用 frozenset,因为 set 对象是可变的且不可散列的。
下面是一个产生上述错误的示例
my_set = {'apple', 'banana'}
# 👇️ using set as an element in another set
# ⛔️ TypeError: unhashable type: 'set'
another_set = {'Alice', 'Bob', my_set}
# 👇️ using set as a key in a dictionary
# ⛔️ TypeError: unhashable type: 'set'
my_dict = {my_set: 'fruits'}
我们不能将集合用作字典中的键或另一个集合中的元素,因为集合对象是可变的和不可散列的。
解决错误的一种方法是使用 frozenset。
my_set = frozenset({'apple', 'banana'})
another_set = {'Alice', 'Bob', my_set}
print(another_set) # 👉️ {'Bob', frozenset({'banana', 'apple'}), 'Alice'}
# checking if element in set
print(frozenset({'apple', 'banana'}) in another_set) # 👉️ True
# ---------------------------------------------------------------
my_dict = {my_set: 'fruits'}
print(my_dict) # 👉️ {'Bob', frozenset({'banana', 'apple'}), 'Alice'}
# 👇️ accessing key in dictionary
print(my_dict[frozenset({'apple', 'banana'})]) # 👉️ fruits
我们使用 frozenset 而不是 set。 frozenset 类接受一个可迭代对象作为参数。
frozenset
是 Python 集合对象的不可变版本,因此它可以用作字典中的键或另一个集合中的元素。
请注意
,我们必须使用相同的方法来访问字典中的键。
或者,如果适合我们的用例,我们可以使用另一种不可变类型,例如元组。
my_tuple = tuple({'apple', 'banana'})
my_set = {'Alice', 'Bob', my_tuple}
print(my_set) # 👉️ {'Alice', 'Bob', ('banana', 'apple')}
print(tuple({'apple', 'banana'}) in my_set) # 👉️ True
# -----------------------------------------------------
my_dict = {my_tuple: 'fruits'}
print(my_dict) # 👉️ {('banana', 'apple'): 'fruits'}
print(my_dict[tuple({'apple', 'banana'})]) # 👉️ 'fruits'
元组对象是不可变的并且是可散列的。
我们还可以通过将项目包装在圆括号而不是方括号中来直接声明元组。
my_tuple = ('a', 'b', 'c')
print(my_tuple) # 👉️ ('a', 'b', 'c')
print(type(my_tuple)) # 👉️ <class 'tuple'>
Python 中的大多数不可变内置对象都是可散列的,而可变对象是不可散列的。
如果一个对象是可散列的,那么它可以用作字典中的键和集合中的元素,因为这些数据结构在内部使用散列值。
可哈希对象包括 - str、int、bool、tuple、frozenset。
不可散列的对象包括 - list、dict、set。
请注意
,元组和 frozensets 仅在其元素可哈希时才可哈希。
我们可以通过将对象传递给内置的 hash()
函数来检查对象是否可散列。
print(hash('hello')) # 👉️ -1210368392134373610
# ⛔️ TypeError: unhashable type: 'set'
print(hash({'a', 'b', 'c'}))
散列函数返回传入对象的散列值(如果有的话)。
哈希值是整数,用于在字典查找期间比较字典键。
可散列对象的散列值在其生命周期内永远不会改变。 这就是为什么大多数不可变对象是可哈希的,而可变对象是不可哈希的。
像集合这样的对象是可变的,因为集合的内容可以改变。
my_set = {'a', 'b'}
my_set.add('c')
print(my_set) # 👉️ {'c', 'a', 'b'}
另一方面,包含原始值的 frozensets 和元组是不可变的(和可散列的)。
字典由键索引,字典中的键可以是任何不可变类型,例如 字符串或数字。
如果元组包含字符串、数字或元组,则它们只能用作字典中的键。
如果 frozensets 或元组包含可变对象(例如列表),则不能将其用作字典中的键或集合中的元素。
如果我们不确定变量存储的对象类型,请使用 type()
函数。
my_set = {'a', 'b'}
print(type(my_set)) # 👉️ <class 'set'>
print(isinstance(my_set, set)) # 👉️ True
my_tuple = ('a', 'b')
print(type(my_tuple)) # 👉️ <class 'tuple'>
print(isinstance(my_tuple, tuple)) # 👉️ True
类型类返回对象的类型。
如果传入的对象是传入类的实例或子类,则 isinstance
函数返回 True。
相关文章
Python for 循环中的下一项
发布时间:2023/04/26 浏览次数:179 分类:Python
-
本文讨论了 Python 中的 for 循环以及如何通过使用 for 循环和示例来跳过列表的第一个元素。
Python While 循环用户输入
发布时间:2023/04/26 浏览次数:148 分类:Python
-
我们可以在 while 循环中使用 input() 函数来输入数据,直到在 Python 中满足某个条件。
在 Python 中将整数转换为罗马数字
发布时间:2023/04/26 浏览次数:87 分类:Python
-
本篇文章将介绍在 Python 中将整数转换为罗马数字。以下是一个 Python 程序的实现,它将给定的整数转换为其等效的罗马数字。
在 Python 中将罗马数字转换为整数
发布时间:2023/04/26 浏览次数:144 分类:Python
-
本文讨论如何在 Python 中将罗马数字转换为整数。 我们将使用 Python if 语句来执行此操作。 我们还将探讨在 Python 中将罗马数字更改为整数的更多方法。
在 Python 中读取 gzip 文件
发布时间:2023/04/26 浏览次数:70 分类:Python
-
本篇文章强调了压缩文件的重要性,并演示了如何在 Python 中使用 gzip 进行压缩和解压缩。
在 Python 中锁定文件
发布时间:2023/04/26 浏览次数:141 分类:Python
-
本文解释了为什么在 Python 中锁定文件很重要。 这讨论了当两个进程在没有锁的情况下与共享资源交互时会发生什么的示例,为什么在放置锁之前知道文件状态很重要,等等
在 Python 中将 PDF 转换为文本
发布时间:2023/04/26 浏览次数:196 分类:Python
-
在本教程中,我们将学习如何使用 Python 使用 PyPDF2、Aspose 和 PDFminer 将 PDF 文档转换为文本文件。
在 Python 中创建临时文件
发布时间:2023/04/26 浏览次数:53 分类:Python
-
本文讲解了tempfile库函数的四个子函数:TemporaryFile、NamedTemporaryFile、mkstemp、TemporaryDirectory。 每个部分都提供了适当的程序,以简化对概念的理解。