Python不可哈希的类型dict问题,为什么这两种方法会有不同的结果

时间:2019-06-14 10:01:33

标签: python dictionary

我偶然发现this question,并想知道为什么我不能这样做:

# this does not work
pipeline = {
    {"resample" : {"type" : "trans", "name" : "resample", "kwargs" : {"rule" : "1min"}}}
}
pipeline

它给出了:

---------------------------------------------------------------------------
TypeError                                 Traceback (most recent call last)
<ipython-input-10-7305ba79e664> in <module>
      1 pipeline = {
----> 2     {"resample" : {"type" : "trans", "name" : "resample", "kwargs" : {"rule" : "1min"}}}
      3 }
      4 pipeline
TypeError: unhashable type: 'dict'

但是我可以这样做:

# this does work
pipeline = dict()
pipeline["resample"] = {"type" : "trans", "name" : "resample", "kwargs" : {"rule" : "1min"}}
pipeline

给出:

{'resample': {'type': 'trans', 'name': 'resample', 'kwargs': {'rule': '1min'}}}

我只是对任何事情都感到好奇,因为就最终结果而言,我感觉自己正在做同样的事情,但是不确定为什么第一种方法会失败,而第二种方法还是可以的。

3 个答案:

答案 0 :(得分:1)

因为您无法将字典项保留在内部。当您尝试声明

pipeline = {
    {"resample" : {"type" : "trans", "name" : "resample", "kwargs" : {"rule" : "1min"}}}
}

您基本上是在尝试创建一个集合,该集合的第一项是字典:

{"resample" : {"type" : "trans", "name" : "resample", "kwargs" : {"rule" : "1min"}}}

但是,您始终可以将管道分别分配给此字典。集要求项目是可哈希的。字典本身在python中不可哈希。您可以在终端中使用任何字典尝试此操作。尝试hash({1: 'a', 2: 'b'}),它应该会给您同样的TypeError: unhashable type: 'dict'错误。

答案 1 :(得分:1)

虽然我认为您可能只打算少使用一对花括号,但我想我会解释为什么获得输出。通过了解Python如何实现字典(以及使用字典实现的集合),可以最好地理解该错误。

字典是一个关联数组。当您将mydict['foo'] = bar写入Python时,会将字符串'foo'哈希到一个数字值中,并使用该值确定将bar放置在哪个内存位置。当您以后想要访问'foo'的值时,Python再次对'foo'进行哈希处理,生成数字值并查找该值所对应的内存位置。

让我们先假设一下,您在错误行中定义了字典,而不是通过分配值来设置集合。您会看到类似以下内容的

keydict = {'foo': bar}
mydict[keydict] = baz

现在,Python必须以某种方式使用字典{'foo': bar}得出一个数值,该字典将映射到存储baz的内存位置。即使您想到了将字典转换为数值的方法,问题仍然是字典是可变的。如果要向keydict添加一个元素,然后使用您的方法将其转换为数值,则该数值将与以前的数值不同。因此,您将不再知道在哪里可以找到baz

出现unhashable type错误是因为字典是可变的,因此其数字哈希值可以更改。当您在第一行中将字典放在集合中时,Python会尝试对其进行哈希处理以决定应将其存储在哪个内存位置。在注意到它是可变类型时,将引发错误。

答案 2 :(得分:0)

字典的构造应该是键:值对,因此在您的情况下,“重采样”是键,而适当的字典就是它的值。您只是试图分配一个包含{“ resample”:{...}}且没有任何键的字典。

如果您尝试这样做,它将按预期工作:

    pipeline = {
        "resample" : {"type" : "trans", "name" : "resample", "kwargs" : {"rule" : "1min"}}
    }

    print(pipeline)
#{'resample': {'type': 'trans', 'name': 'resample', 'kwargs': {'rule': '1min'}}}