1

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

Testerflorida
  • 99
  • 1
  • 1
  • 8
  • Possible duplicate of [Python: Add list to set?](http://stackoverflow.com/questions/1306631/python-add-list-to-set) – badcook Mar 16 '16 at 15:59

3 Answers3

2

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
Yunhe
  • 665
  • 5
  • 10
  • What is going on here? i dont understand why you put dict in front: a = dict(set(dict1.items()) - set(dict2.items())) then what is happening here: a = dict((k, [v]) for (k, v) in zip(a.keys(), a.values())) – Testerflorida Mar 16 '16 at 16:52
  • @Testerflorida, I modified the last 3rd line from a = dict((k, [v])... to a = dict((k, [i for i in v])... Without the two lines, the result would be {2 : (1, 1)}. With the two line, the result is {2: [1, 1]}. Hope it helps. – Yunhe Mar 16 '16 at 17:02
  • It does help I really appreciate it. I just was trying to understand thanks so much – Testerflorida Mar 16 '16 at 17:04
  • @Testerflorida, if it solves your problem, please mark it as an answer :) – Yunhe Mar 16 '16 at 17:06
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().

Community
  • 1
  • 1
niemmi
  • 17,113
  • 7
  • 35
  • 42
1

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!

Jules
  • 973
  • 4
  • 10
  • i changed to tuple but how do i find difference between them? – Testerflorida Mar 16 '16 at 16:09
  • What do you mean by "find the difference between them" – Jules Mar 16 '16 at 16:12
  • dict2 = tuple((k, [v]+[i]) for (k, v) in zip(num_list2,val_list2)) if set(dict2.items()) - set(dict1.items()): I cant use set if i change to tuple – Testerflorida Mar 16 '16 at 16:13
  • Oh ok I understand what you mean. `dict1` should remain a dictionary. Instead you should change the "value" part of the dictionary to be a list. Like so `dict1 = dict((k, tuple([v]+[i])) for (k, v) in zip(num_list,val_list))` – Jules Mar 16 '16 at 16:16