Home > Mobile >  Compare and fetch the missing keys between 2 nested dictionaries
Compare and fetch the missing keys between 2 nested dictionaries

Time:07-14

I am trying to compare 2 nested dictionaries and trying to find the missing keys between them.

Let us say, we have 2 dictionaries d1 and d2 as following.

d = {'A': {'B': {'C': True, 'H': 'h', 'D': {'E': 'e', 'F': 'f'}}}}
e = {'A': {'B': {'C': True, 'D': {'E': 'e', 'F': 'f', 'G': [2, 3, 4, 5, 6, 7]}}}}

The output of difference between d, e should be displayed as follows:

diff = {'A': {'B': {'TESTING': [['H']], 'DEV': [{'D': ['G']}]}}}

I have implemented a logic using for loop which can find the difference only till certain level of nested dictionary. However, to find the difference for inner nests I do not want to end up writing infinite for loops, kindly help me with best solution for this. Thank you!

Below is the code snippet I have implemented:

def compare_yaml(dev_configs, test_configs):
    diff = {}
    for ch in dev_configs.keys():
        for model, value in dev_configs[ch].items():
            diff.update({ch: {model: {'TESTING': [], 'DEV': []}}})
            for k, dv in value.items():
                if isinstance(dv, dict):
                    tv = test_configs[ch][model][k]
                    missing_keys_in_test = list(set(dv.keys()) - set(tv.keys()))
                    missing_keys_in_dev = list(tv.keys() - set(dv.keys()))
                    if missing_keys_in_test:
                        missing_keys_in_test = {k: missing_keys_in_test}
                        diff[ch][model]['TESTING'].append(missing_keys_in_test)
                    if missing_keys_in_dev:
                        missing_keys_in_dev = {k: missing_keys_in_dev}
                        diff[ch][model]['DEV'].append(missing_keys_in_dev)
            else:
                missing_keys_in_test = list(set(dev_configs[ch][model].keys()) - set(test_configs[ch][model].keys()))
                missing_keys_in_dev = list(set(test_configs[ch][model].keys()) - set(dev_configs[ch][model].keys()))
                if missing_keys_in_test:
                    diff[ch][model]['TESTING'].append(missing_keys_in_test)
                if missing_keys_in_dev:
                    diff[ch][model]['DEV'].append(missing_keys_in_dev)

    return diff

    
d = {'A': {'B': {'C': True, 'H': 'h', 'D': {'E': 'e', 'F': 'f'}}}}
e = {'A': {'B': {'C': True, 'D': {'E': 'e', 'F': 'f', 'G': [2, 3, 4, 5, 6, 7]}}}}

diff = compare_yaml(d, e)

CodePudding user response:

There's a library dictdiffer that might help you:

import dictdiffer
d = {'A': {'B': {'C': True, 'H': 'h', 'D': {'E': 'e', 'F': 'f'}}}}
e = {'A': {'B': {'C': True, 'D': {'E': 'e', 'F': 'f', 'G': [2, 3, 4, 5, 6, 7]}}}}
list(dictdiffer.diff(d, e))

# ->
[('add', 'A.B.D', [('G', [2, 3, 4, 5, 6, 7])]),
 ('remove', 'A.B', [('H', 'h')])]
  • Related