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
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.
According to the python doc, you can indeed use the == operator on dictionaries.
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.
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)
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.
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.
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
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With