【问题标题】:type error python unhashable type类型错误 python unhashable 类型
【发布时间】:2016-07-02 15:07:45
【问题描述】:

我正在尝试了解 dict1 和 dict2 之间的区别,但我不断收到错误,有什么帮助吗?

ret = {}
third_value_list =[0,1]
for i in third_value_list:
    #print i
    num_list = [1,2]
    val_list = [0,1]
    dict1 = dict((k, [v]+[i]) for (k, v) in zip(num_list,val_list))
    print dict1
    num_list2= [1,2]
    val_list2 = [0,6]
    dict2 = dict((k, [v]+[i]) for (k, v) in zip(num_list2,val_list2))
    print dict2
if set(dict2.items()) - set(dict1.items()):
    print 'true'
    a = set(dict1.items()) - set(dict2.items())
    ret.update (a)
    print ret

输出:

{1: [0, 0], 2: [1, 0]}

Traceback(最近一次通话最后一次):

文件“C:\Randstad-ISS\workspace\pattern2\src\pat2\t4.py”,第 46 行,在

if set(dict2.items()) - set(dict1.items()):TypeError: unhashable type: 'list'

{1: [0, 0], 2: [6, 0]}

{1: [0, 1], 2: [1, 1]}

{1: [0, 1], 2: [6, 1]}

【问题讨论】:

标签: python key


【解决方案1】:

试试这个代码。主要思想是将dict1和dict2中的[v]+[i]值转换为元组,然后计算dict1和dict2的差值。最后,将元组类型值转换回列表。

ret = {}
third_value_list =[0,1]
for i in third_value_list:
    #print i
    num_list = [1,2]
    val_list = [0,1]
    dict1 = dict((k, tuple([v]+[i])) for (k, v) in zip(num_list,val_list))
    print dict1
    num_list2= [1,2]
    val_list2 = [0,6]
    dict2 = dict((k, tuple([v]+[i])) for (k, v) in zip(num_list2,val_list2))
    print dict2

if set(dict2.items()) - set(dict1.items()):
    print 'true'
    a = dict(set(dict1.items()) - set(dict2.items()))
    a = dict((k, [i for i in v]) for (k, v) in zip(a.keys(), a.values()))
    ret.update (a)
    print ret

【讨论】:

  • 这是怎么回事?我不明白你为什么把 dict 放在前面:a = dict(set(dict1.items()) - set(dict2.items())) 那么这里发生了什么:a = dict((k, [v]) for (k, v) in zip(a.keys(), a.values()))
  • @Testerflorida,我将最后第三行从 a = dict((k, [v])... 修改为 a = dict((k, [i for i in v]).. . 如果没有这两行,结果将是 {2 : (1, 1)}。有了这两行,结果是 {2: [1, 1]}。希望对您有所帮助。
  • 它确实对我有帮助,我真的很感激。我只是想理解非常感谢
  • @Testerflorida,如果它解决了你的问题,请将其标记为答案:)
【解决方案2】:

错误发生在set(dict2.items())。您正在尝试将(1, [0,1])(2, [1,1])(这些是字典中的“项目”)放入一个集合中。要放入集合中,需要对项目进行哈希处理。它们无法被散列,因为它们包含一个列表。列表是不可散列的,因为它可以更改,列表是可变的。只有不可变的对象可以被散列。

列表的不可变版本是一个元组。元组本质上是一个无法更改的列表。常见数据类型还有其他不可变版本,例如 freezesets 而不是集合。

将这些列表更改为元组,您就可以对它们进行散列!

【讨论】:

  • 我改为元组,但我如何找到它们之间的区别?
  • “找出它们之间的区别”是什么意思
  • dict2 = tuple((k, [v]+[i]) for (k, v) in zip(num_list2,val_list2)) if set(dict2.items()) - set(dict1 .items()):如果我更改为元组,我将无法使用 set
  • 哦,好的,我明白你的意思。 dict1 应该仍然是一本字典。相反,您应该将字典的“值”部分更改为列表。像这样dict1 = dict((k, tuple([v]+[i])) for (k, v) in zip(num_list,val_list))
【解决方案3】:

为了将对象添加到集合中,它需要是hashable。只有不可变对象是可散列的,因为 dict1 包含可变的列表,您会得到错误。

来自 Python 文档:

如果一个对象的哈希值在其生命周期内永远不会改变(它需要一个 hash() 方法),并且可以与其他对象进行比较(它需要一个 eq() 或 cmp() 方法)。比较相等的可散列对象必须具有相同的散列值。

哈希性使对象可用作字典键和集合成员,因为这些数据结构在内部使用哈希值。

所有 Python 的不可变内置对象都是可散列的,而没有可变容器(例如列表或字典)是可散列的。默认情况下,作为用户定义类实例的对象是可散列的;它们都比较不相等(除了它们自己),它们的哈希值来自它们的 id()。

【讨论】:

    猜你喜欢
    • 2014-06-27
    • 2013-09-30
    • 2015-06-25
    • 2014-03-04
    • 2013-09-14
    • 2014-11-30
    • 2013-07-06
    • 1970-01-01
    相关资源
    最近更新 更多