Структура словаря (dict -> dict) со списком в нем сравнения - PullRequest
0 голосов
/ 01 июня 2018

Иметь этот dict -> dict -> list list

Хотите сравнить 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

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 голосов
/ 02 июня 2018

Я добавил несколько слов в ваш словарь, чтобы иметь пример для каждого случая:

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 set set

0 голосов
/ 01 июня 2018
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
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...