比较2个字典列表,并将缺失的(不匹配的)字典从一个列表添加到另一个列表

时间:2018-10-19 15:44:02

标签: python python-3.x list dictionary comparison

我有一本字典,其中有另一本字典列表作为其中一个键的值。 我需要遍历此嵌套字典,并将其与另一个字典列表进行比较。应该添加另一个列表中尚未存在的任何词典。字典的嵌套列表如下所示:

{
"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 :(得分:1)

您可以先将现有规则转换为一组规则,以进行有效查找:

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'}

答案 1 :(得分:0)

正如blhsign所建议的,您应该使用一组。这需要将您的规则设置为可哈希的类型。我建议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'}

答案 2 :(得分:0)

如果真正需要比较的唯一值是规则名称,那么您就可以导出当前规则名称的列表,并在循环测试新规则时检查名称是否匹配。

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'
# }

假设根据您的数据集进行名称比较就很重要,那么此方法比转换为一组元组然后在循环中将比较数据转换为元组要快一些。