I have two lists of dictionaries and I'd like to find the difference between them (i.e. what exists in the first list but not the second, and what exists in the second list but not the first list).
The issue is that it is a list of dictionaries
a = [{'a': '1'}, {'c': '2'}]
b = [{'a': '1'}, {'b': '2'}]
set(a) - set(b)
Result
TypeError: unhashable type: 'dict'
Desired Result:
{'c': '2'}
How do I accomplish this?
You can use the in
operator to see if it is in the list
a = [{'a': '1'}, {'c': '2'}]
b = [{'a': '1'}, {'b': '2'}]
>>> {'a':'1'} in a
True
>>> {'a':'1'} in b
True
>>> [i for i in a if i not in b]
[{'c': '2'}]
I'd like to find the difference between them (i.e. what exists in the first list but not the second, and what exists in the second list but not the first list)
According to your definition, you looking for a Symmetric difference:
>>> import itertools
>>> a = [{'a': '1'}, {'c': '2'}]
>>> b = [{'a': '1'}, {'b': '2'}]
>>> intersec = [item for item in a if item in b]
>>> sym_diff = [item for item in itertools.chain(a,b) if item not in intersec]
>>> intersec
[{'a': '1'}]
>>> sym_diff
[{'c': '2'}, {'b': '2'}
Alternatively (using the plain difference as given in your example):
>>> a_minus_b = [item for item in a if item not in b]
>>> b_minus_a = [item for item in b if item not in a]
>>> sym_diff = list(itertools.chain(a_minus_b,b_minus_a))
>>> a_minus_b
[{'c': '2'}]
>>> b_minus_a
[{'b': '2'}]
>>> sym_diff
[{'c': '2'}, {'b': '2'}]
You can also you filter with a lambda
:
If you want the different items in each list:
print filter(lambda x: x not in b,a) + filter(lambda x: x not in a,b)
[{'c': '2'}, {'b': '2'}]
Or just filter(lambda x: x not in b,a)
to get the elements in a
but not in b
If you don't want to create the full list of dicts in memory you can use itertools.ifilter
from itertools import ifilter
diff = ifilter(lambda x: x not in b,a)
Then just iterate over diff:
for uniq in diff:
print uniq