Сравните 2 списка словарей и добавьте отсутствующие (не соответствующие) слова из одного списка в другой. - PullRequest
0 голосов
/ 19 октября 2018

У меня есть словарь, в котором есть другой список словарей в качестве значения для одного из ключей.Мне нужно перебрать этот вложенный словарь и сравнить его с другим списком словарей.Любой словарь, который находится в другом списке, которого нет в этом, должен быть добавлен.Вложенный список словарей выглядит следующим образом:

{
"rules": [
    {
        "name": "Rule 1",
        "severity": "High"
    },
    {
        "name": "Rule 2 ",
        "severity": "Medium"
    }],
"Account":11111,
"Name": "Test Account"
}

Второй словарь выглядит следующим образом:

[{
  "name": "Rule 2",
  "severity": "Medium"
},
{
  "name": "Rule 3",
  "severity": "low"
}]

Таким образом, правило 3 следует добавить в список "rules" в первом словареи правило 2 игнорируется.

Я зашел так далеко, но логика не работает, если я продолжаю идти по этому пути, и приводит к очень сложным вложенным операторам if.Мои навыки программирования очень начинающие:

for k, v in bundle.items():
i = bundle["rules"] 
for entity in i:
    for key, value in entity.items():

Ответы [ 3 ]

0 голосов
/ 19 октября 2018

Как подсказывает blhsign, вы должны использовать набор.Это требует превращения ваших правил в тип hashable.Я предлагаю namedtuple.Затем, вместо того, чтобы перебирать предметы, используйте природу наборов в свою пользу:

from collections import namedtuple

d = {
"rules": [
    {
        "name": "Rule 1",
        "severity": "High"
    },
    {
        "name": "Rule 2",
        "severity": "Medium"
    }],
"Account":11111,
"Name": "Test Account"
}

rule_tuple = namedtuple('Rule', ['name', 'severity'])
d['rules'] = {rule_tuple(**rule) for rule in d['rules']}

new_rules = [
    {
      "name": "Rule 2",
      "severity": "Medium"
    },
    {
      "name": "Rule 3",
      "severity": "low"
    }
]
new_rules = {rule_tuple(**rule) for rule in new_rules}
d['rules'] = d['rules'].union(new_rules)
d

Вывод:

{'rules': {Rule(name='Rule 1', severity='High'),
  Rule(name='Rule 2', severity='Medium'),
  Rule(name='Rule 3', severity='low')},
 'Account': 11111,
 'Name': 'Test Account'}
0 голосов
/ 19 октября 2018

Если единственное значение, которое действительно нужно сравнить, - это имя правила, то вы можете просто получить список текущих имен правил и проверить совпадения имен, просматривая новые правила, подлежащие тестированию.

data = {
    "rules": [{"name": "Rule 1", "severity": "High"}, {"name": "Rule 2", "severity": "Medium"}],
    "Account": 11111,
    "Name": "Test Account"
    }

test_rules = [{"name": "Rule 2", "severity": "Medium"}, {"name": "Rule 3", "severity": "Low"}]

rules = data['rules']
names = [r['name'] for r in rules]

for rule in test_rules:
    if rule['name'] not in names:
        rules.append(rule)

print(data)
# OUTPUT
# {
#     'rules': [
#         {'name': 'Rule 1', 'severity': 'High'},
#         {'name': 'Rule 2', 'severity': 'Medium'},
#         {'name': 'Rule 3', 'severity': 'Low'}
#         ],
#     'Account': 11111,
#     'Name': 'Test Account'
# }

Предполагая, что сравнение имен - это все, что имеет значение на основе вашего набора данных, этот подход немного быстрее, чем преобразование в набор кортежей и затем преобразование данных сравнения в кортежи в цикле.

0 голосов
/ 19 октября 2018

Вы можете сначала преобразовать существующие правила в набор для эффективного поиска:

d = {
"rules": [
    {
        "name": "Rule 1",
        "severity": "High"
    },
    {
        "name": "Rule 2",
        "severity": "Medium"
    }],
"Account":11111,
"Name": "Test Account"
}
new = [{ "name": "Rule 2", "severity": "Medium" }, { "name": "Rule 3", "severity": "low" }]
set_d = set(tuple(r.items()) for r in d['rules'])
for r in new:
    if tuple(r.items()) not in set_d:
        d['rules'].append(r)
print(d)

Это выводит:

{'rules': [{'name': 'Rule 1', 'severity': 'High'}, {'name': 'Rule 2', 'severity': 'Medium'}, {'name': 'Rule 3', 'severity': 'low'}], 'Account': 11111, 'Name': 'Test Account'}

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...