Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/python/358.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181

Warning: file_get_contents(/data/phpspider/zhask/data//catemap/1/list/4.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Python 为什么我不能使用列表作为字典键?_Python_List_Dictionary_Hash - Fatal编程技术网

Python 为什么我不能使用列表作为字典键?

Python 为什么我不能使用列表作为字典键?,python,list,dictionary,hash,Python,List,Dictionary,Hash,为什么我不能使用列表作为字典键 hlst是一个列表。 备忘录是一份口述 if not hlst in memo: # do something else: configurations = memo[hlst] 当我尝试它时,python告诉我hlist是不可损坏的 不能将列表用作键,因为列表是可变的。因为它们是可变的,所以它们不能是可散列的(就像字符串和元组一样)。假设hlist=['a']。想想如果将hlist的内容更改为['b'],会发生什么情况。memo[['a']]会

为什么我不能使用列表作为字典键

hlst是一个列表。 备忘录是一份口述

if not hlst in memo:
    # do something
else:
    configurations = memo[hlst]

当我尝试它时,python告诉我hlist是不可损坏的

不能将列表用作键,因为列表是可变的。因为它们是可变的,所以它们不能是可散列的(就像字符串和元组一样)。假设
hlist=['a']
。想想如果将
hlist
的内容更改为
['b']
,会发生什么情况。
memo[['a']]
会返回什么


要克服这个问题,您可以按照darkryder的评论,将列表转换为一个元组
元组(hlist)

您的问题是缺乏对“哈希”概念的理解

如果您能够计算对象的hashcode,我们将其称为“hashable”

Hashcode(又称hash函数)是一个函数,它接受对象并返回一些值,这些值通常足以将其与其他对象区分开来。这意味着,hashcode在某种程度上应该可用作ID。当然,会有所谓的“hash冲突”(当两个对象具有相同的hashcode时),因为可能的对象比hashcode多得多

对散列函数(用于获取对象的haschode的函数)的约束(比“不同的对象有不同的hashcode”)更重要的是,在对象的整个生命周期中,它应该是相同的

看:我们有一个对象
a
,它有属性/属性
x
y
。为了使散列函数正常工作,您需要确保a的散列不依赖于
x
y

列表的hashcode依赖于其值hashcodes,因此它们本身是不可损坏的。为什么?因为如果您更改列表中的一个元素(或添加一个,或删除一个,等等),它的哈希代码会更改(因为它依赖于这个元素)

现在,回到字典。字典是一个哈希表,可以描述为“简单的内存对数组,索引(X模(数组大小))下有值,第一项有哈希代码X”(这是一个相当简单的概念,但主要概念贯穿语言和实现;对的第一个值称为“键”,第二个值称为“值”,或“项”)。如果要将哈希代码为1234、值为V的列表[A,B]插入到大小为10的哈希表中,然后将该列表的值更改为[A,C](这意味着将haschode更改为5678),则在插入对时([A,B],V)将位于索引1234模10=4处,但更改后应位于索引5678模10=8处

为了使其正常工作,我们需要在每次键对象更改时通知哈希表(这很难看,很难实现,并且占用了很多资源),或者确保键的哈希代码不会像哈希表中的哈希代码那样长时间更改。Python创建者选择了第二个选项,因为它被广泛使用,被证明工作良好且稳定

这就是python有两种有序集合类型的原因之一——列表和元组。正如您可能知道的,元组是不可变的,因此其哈希代码不应更改-因此,它可以用作字典键


注:上面的文字相当简单。列表哈希代码对其元素的依赖性有点棘手。另外,字典作为hashmap的实现并没有在语言引用中定义——它只是说键应该是可散列的,并没有解释为什么。有些实现可以很好地处理不可破坏的对象,但为了符合引用,可以强制使用哈希键。

不知道您在问什么。你的问题不清楚。如果
hlst
是一个列表,那么它不可能在字典中。那你为什么要检查?(如果要将列表添加到字典中,请先将其转换为元组,使用
tuple(hlst)
:只需确保在将任何其他值用作键或检查其存在性之前,始终将其转换为元组)如果这是您的意思,则不能附加dict。也许你想在列表中添加一个dict?这实际上是一个好问题。我重新制定了它,使它更清楚。不能将列表用作键,因为列表是可变的。因为它们是可变的,所以它们不能是可散列的(就像字符串和元组一样)。假设
hlist=['a']
。想想如果您将hlist的内容更改为['b'],会发生什么情况。
memo[[a']
会返回什么?列表是可变的。字典要求键是不可变的,以便键(因此键的散列)保持不变。将其转换为元组或字符串表示形式。或者,如果列表很大,请尝试其他实现。检查问题是,它实际上可能是一个包含列表列表的元组。如何转换所有级别?此外,常规类的实例是可散列的,您也可以对它们进行变异。