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"