TypeError:不可散列的类型:’dict’(Python)

TypeError: unhashable 类型: ‘dict’ (Python)

TypeError: unhashable type: ‘dict’ (Python)

当我们将字典用作另一个字典中的键或用作set. 要解决该错误,请改用 frozenset,或者在将字典用作键之前将其转换为 JSON 字符串。

typeerror 不可散列的类型字典

以下是错误发生方式的 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'}}
我们不能将字典用作字典中的键或 a 中的元素,因为对象是可变的且不可散列的。 setdict

解决错误的一种方法是使用冻结集。

主程序
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我们可以用作字典中的键(和另一个集合中的元素)。

frozenset 是 Pythonset对象的不可变版本,因此它可以用作字典中的键或另一个集合中的元素。

请注意,您必须使用相同的方法来访问字典中的键。

您可以将调用结果存储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 中的大多数不可变内置对象都是可散列的,而可变对象是不可散列的。

如果一个对象是可哈希的,那么它可以用作字典中的键和 a 中的元素set,因为这些数据结构在内部使用哈希值。

可哈希对象包括 – strintbooltuplefrozenset

不可散列的对象包括 – listdictset

请注意,tuplesfrozensets当它们的元素可哈希时,才可哈希。

您可以通过将对象传递给内置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 字符串。

发表评论