Skip to content Skip to sidebar Skip to footer

Dictionary Structure (dict -> Dict) With A List In It Comparison

Have this dict -> dict -> list structure Want to compare 2 structures of this kind. one = {'1iG5NDGVre': {'118': ['test1', 'test2', 'test3', 'tcp', '22', 'Red', '0.0.0.0/0']}

Solution 1:

I added some subkey to your dictionary to have an example for each case:

one = {"1iG5NDGVre": {"116": ["commonkey1", "commonkey2"], "118": ["test1", "test2", "test3", "tcp", "22", "Red", "0.0.0.0/0"],"117": ["test4", "test5", "test6", "tcp", "42", "Fucsia", "0.0.0.0/0"]}}
two = {"1iG5NDGVre": {"116": ["commonkey1", "commonkey2"], "118": ["test100", "test200", "test3", "tcp", "22", "Red", "Blue", "0.0.0.0/0"],"119": ["test10","test11"]}}

where:

  • 116 is present in both, not modified
  • 118 is present in both, modified
  • 117 is present only in one
  • 119 is present only in two

Then we iterate through our dictionary:

def compare(one,two):
    for mainkey in one:
        # Here we are iterating at "1iG5NDGVre" key level
        # We want to know the keys which has been added, removed, and modified
        # keys removed:
        for key in set(one[mainkey].keys()).difference(two[mainkey].keys()):
            print "{0} was removed. Removed values: {1}".format(key, one[mainkey][key])
        # keys added:
        for key in set(two[mainkey].keys()).difference(one[mainkey].keys()):
            print "{0} was added. Added values: {1}".format(key, two[mainkey][key])
        # keys modified
        for key in set(one[mainkey].keys()).intersection(two[mainkey].keys()):
            if set(one[mainkey][key]) ^ set(two[mainkey][key]): print("{0} was modified. New values {1}".format(key, set(one[mainkey][key]) ^ set(two[mainkey][key])))


compare(one,two)
# OUTPUT:
# 117 was removed. Removed values: ['test4', 'test5', 'test6', 'tcp', '42', 'Fucsia', '0.0.0.0/0']
# 119 was added. Added values: ['test10', 'test11']
# 118 was modified. New values set(['Blue', 'test1', 'test2', 'test100', 'test200'])

Here what's happening:

set(one[mainkey].keys()).difference(two[mainkey].keys()) # returns117, aka what is present in'one' but notin'two'set(two[mainkey].keys()).difference(one[mainkey].keys()) # returns119, aka what is present in'two' but notin'one'set(one[mainkey].keys()).intersection(two[mainkey].keys()) # returns116, 118, aka keys present inboth

notice that when we check element present in both, we always return something: an empty list [] if values are equal, or a list with the different values.

Also, we are using sets, which accept only unique values:

set(["a", "a", "b", "b", "b", "c"]) # returns ("a", "b", "c").

this won't be a problem with the dictionaries, since the keys are also unique, but may create some problem with the lists. If you want to work around this problem, you can use list comprehension, which are also a good way to improve the previous code. I suggest you to also have a look on Python set operation

Solution 2:

def compare(one,two):
    if set(one.keys()) != set(two.keys()):
        main_key_added = set(two.keys()) - set(one.keys())
        main_key_removed = set(one.keys()) - set(two.keys())
        print("The main key {} where added".format(main_key_added))
        print("The main key {} where removed".format(main_key_removed))
        return False

    for mainkey in one:
        if set(one[mainkey].keys()) != set(two[mainkey].keys()):
            second_key_added = set(two[mainkey].keys()) - set(one[mainkey].keys())
            second_key_removed = set(one[mainkey].keys()) - set(two[mainkey].keys())
            print("The second key {} where added for main key {}".format(second_key_added, mainkey))
            print("The second key {} where removed for main key".format(second_key_removed, mainkey))
            return False

        for subkey in one[mainkey]:
            if not set(one[mainkey][subkey]) ^ set(two[mainkey][subkey]):
                return False

    return True

Post a Comment for "Dictionary Structure (dict -> Dict) With A List In It Comparison"