Search code examples
pythonpython-3.xpython-2.7dictionarynested-loops

Compare key and values of one nested dictionary in other nested dictionary


I am trying to recursively compare below two python dictionaries:

expectededr = {'uid': 'e579b8cb-7d9f-4c0b-97de-a03bb52a1ec3', 'attempted': {'smpp': {'registeredDelivery': 0}, 'status': 'success', 'OATON': 1, 'OANPI': 1, 'DATON': 1, 'DANPI': 1, 'OA': '12149921220', 'DA': '1514525404'}, 'customerID': 'customer01', 'productID': 'product'}

edr = {'Category': 'NO', 'Type': 'mt', 'uid': 'e579b8cb-7d9f-4c0b-97de-a03bb52a1ec3', 'protocolID': 'smpp', 'direction': 'attempted', 'attempted': {'status': 'success', 'OANPI': 1, 'DATON': 1, 't2': 1512549691602, 'DANPI': 1, 'OA': '12149921220', 'DA': '1514525404', 'smpp': {'fragmented': False, 'sequenceID': 1, 'registeredDelivery': 0, 'messageID': '4e7b48ad-b39e-4e91-a7bb-2de463e4a6ee', 'srcPort': 39417, 'messageType': 4, 'Status': 0, 'ESMClass': 0, 'dstPort': 0, 'size': 0}, 'OATON': 1, 'PID': 0, 't1': 1512549691602}, 'customerID': 'customer01', 'productID': 'product'}  

I am trying to compare the in a way that find and compare the key and value of first dictionary in second and if matching then print PASS else print FAIL.

for key in expectededr:
   if expectededr[key] == edr[key]:
       print("PASS")
   else:
       print("FAIL")

Output:

FAIL
PASS
PASS
PASS

Above code is not able to compare all the keys and values as these are nested dictionaries.
As you can see below, if i print key and values above i see that its not going in sub dictionary and missing their keys:

for key in expectededr:
    if expectededr[key] == edr[key]:
        print(expectededr[key])
        print(edr[key])

Output:

customer01
customer01
e579b8cb-7d9f-4c0b-97de-a03bb52a1ec3
e579b8cb-7d9f-4c0b-97de-a03bb52a1ec3
product
product

Could someone help to update this code so that I can do the comparision in these nested dictionaries ?


Solution

  • One way is to flatten the dictionaries and then compare if the keys match.

    So Lets initialiaze your dicts first:

    In [23]: expectededr = {'uid': 'e579b8cb-7d9f-4c0b-97de-a03bb52a1ec3', 'attempted': {'smpp': {'registeredDelivery': 0}, 'status': 'success', 'OATON': 1, 'OANP
        ...: I': 1, 'DATON': 1, 'DANPI': 1, 'OA': '12149921220', 'DA': '1514525404'}, 'customerID': 'customer01', 'productID': 'product'}
        ...: 
        ...: edr = {'Category': 'NO', 'Type': 'mt', 'uid': 'e579b8cb-7d9f-4c0b-97de-a03bb52a1ec3', 'protocolID': 'smpp', 'direction': 'attempted', 'attempted': {'
        ...: status': 'success', 'OANPI': 1, 'DATON': 1, 't2': 1512549691602, 'DANPI': 1, 'OA': '12149921220', 'DA': '1514525404', 'smpp': {'fragmented': False, '
        ...: sequenceID': 1, 'registeredDelivery': 0, 'messageID': '4e7b48ad-b39e-4e91-a7bb-2de463e4a6ee', 'srcPort': 39417, 'messageType': 4, 'Status': 0, 'ESMCl
        ...: ass': 0, 'dstPort': 0, 'size': 0}, 'OATON': 1, 'PID': 0, 't1': 1512549691602}, 'customerID': 'customer01', 'productID': 'product'}  
        ...: 
    

    For flattening your dictionaries, we can use the approach suggested in Flatten nested Python dictionaries, compressing keys:

    In [24]: import collections
        ...: 
        ...: def flatten(d, parent_key='', sep='_'):
        ...:     items = []
        ...:     for k, v in d.items():
        ...:         new_key = parent_key + sep + k if parent_key else k
        ...:         if isinstance(v, collections.MutableMapping):
        ...:             items.extend(flatten(v, new_key, sep=sep).items())
        ...:         else:
        ...:             items.append((new_key, v))
        ...:     return dict(items)
        ...: 
    

    And generated flattened dicts

    In [25]: flat_expectededr = flatten(expectededr)
    
    In [26]: flat_edr = flatten(edr)
    

    Now its a simple comparison:

    In [27]: for key in flat_expectededr:
        ...:     if flat_edr.get(key) == flat_expectededr[key]:
        ...:         print "PASS"
        ...:     else:
        ...:         print "FAIL"
    PASS
    PASS
    PASS
    PASS
    PASS
    PASS
    PASS
    PASS
    PASS
    PASS
    PASS