TypeError: unhashable 类型: ‘list’ (Python)
TypeError: unhashable type: ‘list’ (Python)
当我们将列表用作字典中的键或集合中的元素时,会出现 Python“TypeError: unhashable type: ‘list’”。要解决该错误,请将列表转换为元组,例如tuple(my_list)
,因为list
对象是可变的和不可散列的。
以下是错误发生方式的 2 个示例。
# 👇️ using list as a key in dictionary # ⛔️ TypeError: unhashable type: 'list' my_dict = {'name': 'Alice', ['dev', 'test']: 'tasks'} # 👇️ using list as an element in a set # ⛔️ TypeError: unhashable type: 'list' my_set = {['a', 'b', 'c']}
set
您可以通过将列表转换为tuple
.
my_dict = {'name': 'Alice', tuple(['dev', 'test']): 'tasks'} print(my_dict) # 👉️ {'name': 'Alice', ('dev', 'test'): 'tasks'} # 👇️ same approach when accessing key print(my_dict[tuple(['dev', 'test'])]) # 👉️ tasks my_set = {tuple(['a', 'b', 'c'])} print(my_set) # 👉️ {('a', 'b', 'c')}
元组对象是不可变的和可散列的。
您还可以通过将项目包装在圆括号而不是方括号中来直接声明元组。
my_tuple = ('a', 'b', 'c') print(my_tuple) # 👉️ ('a', 'b', 'c') print(type(my_tuple)) # 👉️ <class 'tuple'>
另一种解决方案是将列表转换为 JSON 字符串。
import json # 👇️ convert list to JSON string my_json = json.dumps(['dev', 'test']) my_dict = {'name': 'Alice', my_json: 'tasks'} print(my_dict) # 👉️ {'name': 'Alice', '["dev", "test"]': 'tasks'} # 👇️ use JSON string for key lookup print(my_dict[json.dumps(['dev', 'test'])]) # 👉️ tasks
json.dumps方法将 Python 对象转换为 JSON 格式的字符串。这是有效的,因为字符串是不可变的和可散列的。
相反,
json.loads方法将 JSON 字符串解析为本机 Python 对象,例如
my_list = 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: 'list' print(hash(['a', 'b']))
散列函数返回传入对象的散列值(如果有的话)。
哈希值是整数,用于在字典查找期间比较字典键。
像列表这样的对象是可变的,因为列表的内容可以改变。
my_list = ['a', 'b', 'c'] my_list[0] = 'z' print(my_list) # ['z', 'b', 'c']
另一方面,包含原始值的元组是不可变的(和可散列的)。
my_tuple = ('a', 'b', 'c') # ⛔️ TypeError: 'tuple' object does not support item assignment my_tuple[0] = 'z'
字典由键索引,字典中的键可以是任何不可变类型,例如字符串或数字。
如果元组包含可变对象(例如列表),则它不能用作字典中的键或set
.
如果您不确定变量存储的对象类型,请使用type()
类。
my_list = ['a', 'b', 'c'] print(type(my_list)) # 👉️ <class 'list'> print(isinstance(my_list, list)) # 👉️ True my_tuple = ('a', 'b', 'c') print(type(my_tuple)) # 👉️ <class 'tuple'> print(isinstance(my_tuple, tuple)) # 👉️ True
类型类返回对象的类型。
如果传入的对象是传入类的实例或子类,则isinstance
函数返回。True
结论
当我们将列表用作字典中的键或集合中的元素时,会出现 Python“TypeError: unhashable type: ‘list’”。要解决该错误,请将列表转换为元组,例如tuple(my_list)
,因为list
对象是可变的和不可散列的。