基于另一个列表中的值操作字典列表



所以基本上我有三个这样的列表:

list1 = [{
    'IP' : "1.1.1.1", 
    'ID' : 1,
    },
    {
    'IP' : "2.2.2.2", 
    'ID' : 2
    }]
list2 = [{
    'vulnerability_id' : 4567, 
    'ID' : 1,
    },
    {
    'vulnerability_id' : 6578, 
    'ID' : 2
    }]
list3 = [{
    'vulnerability_id' : 4567, 
    'description' : 'blah',
    },
    {
    'vulnerability_id' : 6578, 
    'description' : 'blah blah'
    }]

我需要做的是基于IP获取漏洞的描述,但这可能需要某种列表理解,我不确定如何去做。(并把它放在新字典里)

我需要检查我拥有的 IP 值,比如 1.1.1.1,然后将其 ID 与 list2 进行比较,然后比较 list3 中相关的"vulnerability_id"。

任何帮助将不胜感激,如果这没有意义,请说,我会尝试扩展。

这在计算方面真的很重,但你只有列表作为数据源,所以,这是我的"解决方案":

results = []
for ip_info in list1:
    result = {}
    result['ip'] = ip_info['IP']
    result['vulnerability'] = next((
            vuln_info['vulnerability_id']
            for vuln_info in list2
            if vuln_info['ID'] == ip_info['ID']
        ),None)
    result['description'] = next((
            desc_info['description']
            for desc_info in list3
            if desc_info['vulnerability_id'] == result['vulnerability']
        ),None)
    results.append(result)

结果:

[{'description': 'blah', 'ip': '1.1.1.1', 'vulnerability': 4567},
 {'description': 'blah blah', 'ip': '2.2.2.2', 'vulnerability': 6578}]

编辑:根据我的答案和@Alex霍尔答案进行改进:

def find(l, match, v, k):
    return next((x[k] for x in l if x[match] == v), None)
results = []
for ip_info in list1:
    ip = ip_info['IP']
    _id = ip_info['ID']
    vul = find(list2, 'ID', _id, 'vulnerability_id')
    desc = find(list3, 'vulnerability_id', vulnerability, 'description')    
    results.append(dict(ip=ip, vulnerability=vul, description=desc))
list1 = [
    {
        'IP': '1.1.1.1',
        'ID': 1,
    },
    {
        'IP': '2.2.2.2',
        'ID': 2
    }]
list2 = [
    {
        'vulnerability_id': 4567,
        'ID': 1,
    },
    {
        'vulnerability_id': 6578,
        'ID': 2
    }]
list3 = [
    {
        'vulnerability_id': 4567,
        'description': 'blah',
    },
    {
        'vulnerability_id': 6578,
        'description': 'blah blah'
    }]

def find(data, key, value):
    for row in data:
        if row[key] == value:
            return row
    raise ValueError('Row with %s = %s not found' % (key, value))

ID = find(list1, 'IP', '1.1.1.1')['ID']
vulnerability_id = find(list2, 'ID', ID)['vulnerability_id']
print(find(list3, 'vulnerability_id', vulnerability_id)['description'])

对于这样的事情,我真的很喜欢使用熊猫包。我能够做这样的事情:

import pandas as pd
list1 = [{
'IP' : "1.1.1.1", 
'ID' : 1,
},
{
'IP' : "2.2.2.2", 
'ID' : 2
}]
list2 = [{
'vulnerability_id' : 4567, 
'ID' : 1,
},
{
'vulnerability_id' : 6578, 
'ID' : 2
}]
list3 = [{
'vulnerability_id' : 4567, 
'description' : 'blah',
},
{
'vulnerability_id' : 6578, 
'description' : 'blah blah'
}]
df_1 = pd.DataFrame(list1)
df_2 = pd.DataFrame(list2)
df_3 = pd.DataFrame(list3)
output = df_1.merge(df_2).merge(df_3)
print output
ID       IP  vulnerability_id description
 1  1.1.1.1              4567        blah
 2  2.2.2.2              6578   blah blah

这也将为您提供最后格式良好的表格。您无需做额外的工作!合并操作利用了字典键的命名方式。由于 list1 和 list2 都有共同的 id,因此它实质上是对 id 列执行内部连接。然后使用生成的框架的vulnerability_id列与 list3 联接。当您有多个公共键时,这会变得更加复杂(从某种意义上说,您必须使用一些 kwarg 才能使用合并函数来处理多余的重叠),但在这种情况下,它:)工作得很好。缺点是它确实需要安装外部软件包,而上面提到的两种解决方案不需要。

相关内容

  • 没有找到相关文章

最新更新