TypeError: unhashable 类型: ‘dict’ (Python)
TypeError: unhashable type: ‘dict’ (Python)
当我们将字典用作另一个字典中的键或用作set
. 要解决该错误,请改用 frozenset,或者在将字典用作键之前将其转换为 JSON 字符串。
以下是错误发生方式的 2 个示例。
# 👇️ using dictionary as a key in a dictionary # ⛔️ TypeError: unhashable type: 'dict' my_dict = {'name': 'Alice', {'country': 'Austria'}: 'address'} # 👇️ using dictionary as an element in a set # ⛔️ TypeError: unhashable type: 'dict' my_set = {{'name': 'Alice'}}
set
dict
解决错误的一种方法是使用冻结集。
my_key = {'country': 'Austria'} key = frozenset(my_key.items()) print(key) # 👉️ frozenset({('country', 'Austria')}) my_dict = {'name': 'Alice', key: 'address'} # 👇️ when you have to access the key print(my_dict[frozenset(my_key.items())]) # 👉️ 'address'
dict.items方法返回字典
项((键,值)对)的新视图。
我们使用字典的项目来创建一个frozenset
我们可以用作字典中的键(和另一个集合中的元素)。
set
对象的不可变版本,因此它可以用作字典中的键或另一个集合中的元素。请注意,您必须使用相同的方法来访问字典中的键。
您可以将调用结果存储frozenset(my_key.items())
在变量中,并在设置或访问字典中的键时重用 frozenset。
另一种方法是在将字典用作键之前将其转换为 JSON 字符串。
import json # 👇️ convert dictionary to JSON string my_json = json.dumps({'country': 'Austria'}) my_dict = {'name': 'Alice', my_json: 'address'} print(my_dict) # 👉️ {'name': 'Alice', '{"country": "Austria"}': 'address'} # 👇️ when you have to access the key in the dictionary print(my_dict[json.dumps({'country': 'Austria'})]) # 👉️ address
json.dumps方法将 Python 对象转换为 JSON 格式的字符串。这是有效的,因为字符串是不可变的和可散列的。
相反,
json.loads方法将 JSON 字符串解析为本机 Python 对象,例如
my_dict = json.loads(my_json_str)
.
Python 中的大多数不可变内置对象都是可散列的,而可变对象是不可散列的。
set
,因为这些数据结构在内部使用哈希值。可哈希对象包括 – str
、int
、bool
、tuple
、frozenset
。
不可散列的对象包括 – list
、dict
、set
。
请注意,tuples
仅frozensets
当它们的元素可哈希时,才可哈希。
您可以通过将对象传递给内置hash()
函数来检查对象是否可哈希。
print(hash('hello')) # 👉️ -1210368392134373610 # ⛔️ TypeError: unhashable type: 'dict' print(hash({'name': 'Alice'}))
散列函数返回传入对象的散列值(如果有的话)。
哈希值是整数,用于在字典查找期间比较字典键。
像字典这样的对象是可变的,因为 a 的内容dict
可以改变。
my_dict = {'name': 'Alice'} my_dict['name'] = 'Bob' print(my_dict) # 👉️ {'name': 'Bob'}
另一方面,包含原始值的 fronzenset 和元组对象是不可变的(和可散列的)。
字典由键索引,字典中的键可以是任何不可变类型,例如字符串或数字。
如果 frozenset 或元组包含可变对象(例如列表),则不能将其用作字典中的键或set
.
如果您不确定变量存储的对象类型,请使用type()
类。
my_dict = {'name': 'Alice'} print(type(my_dict)) # 👉️ <class 'dict'> print(isinstance(my_dict, dict)) # 👉️ True my_str = 'hello' print(type(my_str)) # 👉️ <class 'str'> print(isinstance(my_str, str)) # 👉️ True
类型类返回对象的类型。
如果传入的对象是传入类的实例或子类,则isinstance
函数返回。True
结论
当我们将字典用作另一个字典中的键或用作set
. 要解决该错误,请改用 frozenset,或者在将字典用作键之前将其转换为 JSON 字符串。