Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Compare dictionaries ignoring specific keys

How can I test if two dictionaries are equal while taking some keys out of consideration. For example,

equal_dicts(     {'foo':1, 'bar':2, 'x':55, 'y': 77 },     {'foo':1, 'bar':2, 'x':66, 'z': 88 },     ignore_keys=('x', 'y', 'z') ) 

should return True.

UPD: I'm looking for an efficient, fast solution.

UPD2. I ended up with this code, which appears to be the fastest:

def equal_dicts_1(a, b, ignore_keys):     ka = set(a).difference(ignore_keys)     kb = set(b).difference(ignore_keys)     return ka == kb and all(a[k] == b[k] for k in ka) 

Timings: https://gist.github.com/2651872

like image 234
georg Avatar asked May 07 '12 10:05

georg


People also ask

How do you compare keys in two dictionaries?

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 == operator be used on dictionaries?

According to the python doc, you can indeed use the == operator on dictionaries.

Should dictionaries should be equal?

Problem: Current implementation of "Dictionaries Should Be Equal" returns true if two dictionaries are identical. Sometimes we need to compare two dictionaries by ignoring some keys. i. e. If we have large dictionaries and one dictionary does not have some keys at nth level but still keyword should return True for all other keys if matches.

How do you compare two dictionaries in Python?

For simple dictionaries, comparing them is usually straightforward. You can use the == operator, and it will work. However, when you have specific needs, things become harder. The reason is, Python has no built-in feature allowing us to: assert nested dictionaries are equal (deep equality comparison)

How to check if a dictionary key is forged or not?

Actual dictionary does not contain "Forged Source" key. If key is 1st or 2nd level we can pop key and compare it but if we want to ignore any key which is at the nth level it is very difficult.

What happens if one dictionary does not have keys at nth level?

If we have large dictionaries and one dictionary does not have some keys at nth level but still keyword should return True for all other keys if matches . Take example of following two dictionaries. expected_dict is my expected dictionary and Actual dictionary is created from UI data. Actual dictionary does not contain "Forged Source" key.


1 Answers

def equal_dicts(d1, d2, ignore_keys):     d1_filtered = {k:v for k,v in d1.items() if k not in ignore_keys}     d2_filtered = {k:v for k,v in d2.items() if k not in ignore_keys}     return d1_filtered == d2_filtered 

EDIT: This might be faster and more memory-efficient:

def equal_dicts(d1, d2, ignore_keys):     ignored = set(ignore_keys)     for k1, v1 in d1.iteritems():         if k1 not in ignored and (k1 not in d2 or d2[k1] != v1):             return False     for k2, v2 in d2.iteritems():         if k2 not in ignored and k2 not in d1:             return False     return True 
like image 142
eumiro Avatar answered Oct 08 '22 03:10

eumiro