字典结构(字典 -> 字典)与其中的列表比较



有这个字典 ->字典 ->列表结构

想要比较 2 种此类结构。

one = {"1iG5NDGVre": {"118": ["test1", "test2", "test3", "tcp", "22", "Red", "0.0.0.0/0"]}}
two = {"1iG5NDGVre": {"118": ["test1", "test2", "test3", "tcp", "22", "Red", "Blue", "0.0.0.0/0"]}}

这段代码效果很好:

def compare(one,two):
for mainkey in one:
for subkey in one[mainkey]:
return set(one[mainkey][subkey]) ^ set(two[mainkey][subkey])

但是,当dict -> dict具有或多或少的键时,应由添加或删除键以及所有列表值的函数返回。

此外,如果列表被修改,它应该由修改列表的程序返回。

有人可以帮忙吗?

它几乎用于比较两个 JSON,我想看看何时删除、添加键或修改其值。

更新 1:

我还在学习 Python

对于此结构:

one = {"1iG5NDGVre": {"118": ["test1", "test2", "test3", "tcp", "22", "Red", "0.0.0.0/0"]}}
two = {"1iG5NDGVre": {"118": ["test1", "test2", "test3", "tcp", "22", "Red", "Blue", "0.0.0.0/0"]},"119": ["test10","test11"]}

它不起作用。

它应该打印为输出:

118 was modified. New values Blue. 119 was added with values test10 test11

对于这些方案:

1.

one = {"1iG5NDGVre": {"118": ["test1", "test2", "test3", "tcp", "22", "Red", "0.0.0.0/0"]}}
two = {"1iG5NDGVre": }

应打印为输出:

118 was removed with values test1 test2 test3 tcp 22 Red 0.0.0.0/0

阿拉伯数字。

one = {"1iG5NDGVre": {"118": ["test1", "test2", "test3", "tcp", "22", "Red", "0.0.0.0/0"]}}
two = {"1iG5NDGVre": {"118": ["test100", "test200", "test3", "tcp", "22", "Red", "Blue", "0.0.0.0/0"]},"119": ["test10","test11"]}

应打印为输出:

118 was modifed. New values test100 test200

我想涵盖所有可能的情况。我这样做就像我所说的 JSON 比较一样。

我在字典中添加了一些子项,以便为每种情况提供一个示例:

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"]}}

哪里:

  • 116 存在于两者中,未修改
  • 118 存在于两者中,修改
  • 117 仅存在于one
  • 119 仅存在于two

然后我们遍历字典:

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'])

这是发生了什么:

set(one[mainkey].keys()).difference(two[mainkey].keys()) # returns 117, aka what is present in 'one' but not in 'two'
set(two[mainkey].keys()).difference(one[mainkey].keys()) # returns 119, aka what is present in 'two' but not in 'one'
set(one[mainkey].keys()).intersection(two[mainkey].keys()) # returns 116, 118, aka keys present in both

请注意,当我们检查两者中都存在的元素时,我们总是返回一些东西:一个空列表[]值是否相等,或者一个具有不同值的列表。

此外,我们使用sets,它只接受唯一值:

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

这对于字典来说不是问题,因为键也是唯一的,但可能会给列表带来一些问题。如果你想解决这个问题,你可以使用列表推导,这也是改进前面代码的好方法。我建议你也看看 Python 集合操作

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

最新更新