简体   繁体   中英

type error python unhashable type

I am trying to get the difference between dict1 and dict2 but i keep getting error any help?

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

Outputs:

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

Traceback (most recent call last):

File "C:\\Randstad-ISS\\workspace\\pattern2\\src\\pat2\\t4.py", line 46,in

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]}

In order to add the object to the set it needs to be hashable . Only immutable objects are hashable and since dict1 contains lists which are mutable you get the error.

From Python documentation:

An object is hashable if it has a hash value which never changes during its lifetime (it needs a hash () method), and can be compared to other objects (it needs an eq () or cmp () method). Hashable objects which compare equal must have the same hash value.

Hashability makes an object usable as a dictionary key and a set member, because these data structures use the hash value internally.

All of Python's immutable built-in objects are hashable, while no mutable containers (such as lists or dictionaries) are. Objects which are instances of user-defined classes are hashable by default; they all compare unequal (except with themselves), and their hash value is derived from their id().

The error happens in set(dict2.items()) . You are trying to place (1, [0,1]) and (2, [1,1]) (These are the the "items" in the dictionary) into a set. To be placed into the set the items need to be hashed. They are unable to be hashed because they contain a list. A list is unhashable because it can be changed, a list is mutable. Only immutable objects can be hashed.

The immutable version of a list is a tuple. A tuple is essentially a list that cannot be changed. There are other immutable versions of common data types such as frozensets instead of sets.

Change those lists to tuples and you'll be able to hash them!

Try this code. The main idea is convert the [v]+[i] values in dict1 and dict2 to tuple, then calculate the difference of dict1 and dict2. Finally, convert the tuple type values back to list.

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

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM