Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Comparing 2 lists consisting of dictionaries with unique keys in python

I have 2 lists, both of which contain same number of dictionaries. Each dictionary has a unique key. There is a match for each dictionary of the first list in the second list, that is a dictionary with a unique key exists in the other list. But the other elements of such 2 dictionaries may vary. For example:

list_1 = [             {                 'unique_id': '001',                 'key1': 'AAA',                 'key2': 'BBB',                 'key3': 'EEE'              },              {                 'unique_id': '002',                 'key1': 'AAA',                 'key2': 'CCC',                 'key3': 'FFF'              }          ]   list_2 = [              {                 'unique_id': '001',                 'key1': 'AAA',                 'key2': 'DDD',                 'key3': 'EEE'              },              {                 'unique_id': '002',                 'key1': 'AAA',                 'key2': 'CCC',                 'key3': 'FFF'              }          ] 

I want to compare all elements of 2 matching dictionaries. If any of the elements are not equal, I want to print the none-equal elements.

Would you please help?

like image 581
alwbtc Avatar asked Mar 23 '12 19:03

alwbtc


People also ask

How do I compare two dictionary keys and values in Python?

Python List cmp() Method. The compare method cmp() is used in Python to compare values and keys of two dictionaries. If method returns 0 if both dictionaries are equal, 1 if dic1 > dict2 and -1 if dict1 < dict2.

Can 2 lists be compared in Python?

Using list.sort() method sorts the two lists and the == operator compares the two lists item by item which means they have equal data items at equal positions. This checks if the list contains equal data item values but it does not take into account the order of elements in the list.

How do you compare two lists the same in Python?

A straightforward way to check the equality of the two lists in Python is by using the equality == operator. When the equality == is used on the list type in Python, it returns True if the lists are equal and False if they are not.


2 Answers

Assuming that the dicts line up like in your example input, you can use the zip() function to get a list of associated pairs of dicts, then you can use any() to check if there is a difference:

>>> list_1 = [{'unique_id':'001', 'key1':'AAA', 'key2':'BBB', 'key3':'EEE'},                {'unique_id':'002', 'key1':'AAA', 'key2':'CCC', 'key3':'FFF'}] >>> list_2 = [{'unique_id':'001', 'key1':'AAA', 'key2':'DDD', 'key3':'EEE'},               {'unique_id':'002', 'key1':'AAA', 'key2':'CCC', 'key3':'FFF'}] >>> pairs = zip(list_1, list_2) >>> any(x != y for x, y in pairs) True 

Or to get the differing pairs:

>>> [(x, y) for x, y in pairs if x != y] [({'key3': 'EEE', 'key2': 'BBB', 'key1': 'AAA', 'unique_id': '001'}, {'key3': 'EEE', 'key2': 'DDD', 'key1': 'AAA', 'unique_id': '001'})] 

You can even get the keys which don't match for each pair:

>>> [[k for k in x if x[k] != y[k]] for x, y in pairs if x != y] [['key2']] 

Possibly together with the associated values:

>>> [[(k, x[k], y[k]) for k in x if x[k] != y[k]] for x, y in pairs if x != y] [[('key2', 'BBB', 'DDD')]] 

NOTE: In case you're input lists are not sorted yet, you can do that easily as well:

>>> from operator import itemgetter >>> list_1, list_2 = [sorted(l, key=itemgetter('unique_id'))                        for l in (list_1, list_2)] 
like image 177
Niklas B. Avatar answered Oct 17 '22 10:10

Niklas B.


The fastest and most comprehensive way would be, to use two sets of tuples:

set_list1 = set(tuple(sorted(d.items())) for d in sorted(list1)) set_list2 = set(tuple(sorted(d.items())) for d in sorted(list2))      

(if your list is already sorted, simply remove the list sort to save performance)

Find overlapping using intersection:

set_overlapping = set_list1.intersection(set_list2) 

Find difference using symmetric_difference

set_difference = set_list1.symmetric_difference(set_list2) 

Convert tuple back to dict

 for tuple_element in set_difference:      list_dicts_difference.append(dict((x, y) for x, y in tuple_element)) 
like image 38
gies0r Avatar answered Oct 17 '22 08:10

gies0r