字典结构(字典 - >字典),其中有一个列表比较

时间:2018-06-01 12:57:02

标签: python python-2.7 dictionary

有这个词 - > dict - >列表结构

想要比较这种结构。

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

2

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比较一样,这样做。

2 个答案:

答案 0 :(得分:1)

我在你的词典中添加了一些子键,以便为每个案例提供一个示例:

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").

这对字典不会有问题,因为密钥也是唯一的,但可能会对列表产生一些问题。如果您想解决此问题,可以使用list comprehension,这也是改进以前代码的好方法。我建议你也看看Python set operation

答案 1 :(得分:0)

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