类型错误:不可散列的类型:“列表”(Python)

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

TypeError: unhashable type: ‘list’ (Python)

当我们将列表用作字典中的键或集合中的元素时,会出现 Python“TypeError: unhashable type: ‘list’”。要解决该错误,请将列表转换为元组,例如tuple(my_list),因为list对象是可变的和不可散列的。

typeerror 不可散列的类型列表

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

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

可哈希对象包括 – strintbooltuplefrozenset

不可散列的对象包括 – listdictset

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

您可以通过将对象传递给内置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对象是可变的和不可散列的。

发表评论