类型错误python unhashable类型

时间:2016-03-16 15:53:27

标签: python key

我正在尝试区分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]}

追踪(最近一次呼叫最后一次):

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

如果设置(dict2.items()) - set(dict1.items()):TypeError:不可用类型:'list'

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

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

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

3 个答案:

答案 0 :(得分:1)

为了将对象添加到集合中,它必须是hashable。只有不可变对象是可以清除的,因为dict1包含可变的列表,你会得到错误。

来自Python文档:

  

如果对象具有在其生命周期内永远不会更改的哈希值(它需要哈希()方法),并且可以与其他对象进行比较(它需要),则该对象是可清除的eq ()或 cmp ()方法)。比较相等的Hashable对象必须具有相同的哈希值。

     

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

     

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

答案 1 :(得分:1)

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

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

将这些列表更改为元组,您将能够对它们进行哈希处理!

答案 2 :(得分: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