从多个词典中提取数据

时间:2012-01-26 22:07:36

标签: python dictionary

我的数据结构:

phase1_hits = {
    '1.2.3.4': {'hits': 3, 'internal': '10.28.30.153', 'public_additional': ['8.2.17.14'], 'list': 'Red', 'internal_additional': ['10.17.100.74', '10.19.70.77', '10.28.30.153']},
    '2.3.4.5': {'hits': 19, 'internal': '10.19.40.175', 'public_additional': ['1.2.227.49'], 'list': 'Red', 'internal_additional': ['10.19.40.175']},
    '12.23.34.45': {'hits': 52, 'internal': '192.168.164.32', 'public_additional': ['8.2.17.14'], 'list': 'Orange', 'internal_additional': ['192.168.164.32', '192.168.164.42', '192.168.164.49']},
    '8.8.8.8': {'hits': 5, 'internal': '192.168.1.10', 'public_additional': ['8.8.87.153', '1.2.3.4'], 'list': 'Green', 'internal_additional': ['192.168.168.250']}
}


phase2_hits = {
    97536: {'ip.dst': ['8.2.17.14'], 'ip.src': ['10.28.30.153']},
    60096: {'ip.dst': ['8.2.17.14'], 'ip.src': ['192.168.164.42']}, 
    43140: {'ip.dst': ['8.2.17.9'], 'ip.src': ['10.153.134.201']},
    43789: {'ip.dst': ['10.28.30.153'], 'ip.src': ['8.2.17.9']},
    89415: {'ip.dst': ['8.2.17.14'], 'ip.src': ['10.153.134.200']}
}

有关数据结构的事实(可能这些都不重要?):

  • phase1_hits键将始终为公共IP
  • phase1_hits public_additional和internal_additional 可能为空
  • phase2_hits私有IP可能出现在ip.src或.dst
  • phase2_hits ip.src和.dst将始终只在列表中有一个项目(是的,我知道这是一个愚蠢的结构,但我无法控制它)
  • 因为私有IP出现在phase1_hits并不意味着它会出现在phase2_hits中,所以如果它不出现我只需要phase1_hits信息就可以了

如果在phase2_hits中看到phase1_hits internal或internal_additional IP,我想提取相应的:

  • phase1_hits key
  • phase1_hits internal(或internal_additional - 在phase2_hits中看到的任何一个)
  • phase1_hits hits
  • phase1_hits list
  • phase2_hits key
  • phase2_hits ip.src或.dst(以查询的内部或内部附加地址为准)

提取的关键概念是匹配哪些私有IP与哪些公共IP进行通信。此外,如果它可以帮助我重组phase1_hits并使用不同的密钥。

1 个答案:

答案 0 :(得分:1)

matches = []
for ip1 in phase1_hits:
    subdict1 = phase1_hits[ip1]
    internal_ips = [subdict1['internal']] + subdict1['internal_additional']
    hits = subdict1['hits']
    color_list = subdict1['list']
    for ip2 in phase2_hits:
        subdict2 = phase2_hits[ip2]
        phase2_ips = subdict2['ip.dst'] + subdict2['ip.src']
        overlap = [i for i in internal_ips if i in phase2_ips]
        if len(overlap) > 0:
            temp = (ip1, overlap, hits, color_list, ip2, [i for i in phase2_ips if i in overlap])
            matches.append(temp)

以下是解释:

matches = []

您需要将数据存储在稍后可以更改/使用它的位置。列表是最简单的,因为它可以根据您拥有的数据和更改的元素数量轻松更改大小。虽然字典是可行的,但效率不高,特别是因为你正在寻找单个匹配并且不想创建指向特定数据的指针。

for ip1 in phase1_hits:

您可以通过将其视为一个列表来遍历字典中的键(即,不需要调用.keys()函数,因为您没有更改/删除字典中的键。)

    subdict1 = phase1_hits[ip1]
    internal_ips = [subdict1['internal']] + subdict1['internal_additional']
    hits = subdict1['hits']
    color_list = subdict1['list']
为了便于阅读,我把子字典别名;但是,没有必要。在接下来的行中,我利用了Python的本地列表__add__,它简单地将一个列表的元素附加到另一个列表并创建一个新列表,因为internal_ips有时可以有多个元素。然后,因为您想要在子条目中使用hits'list'值,我创建了color_list。注意我没有将它命名为与键相同,因为这样做会与Python list变量类型的本机命名空间冲突。

    for ip2 in phase2_hits:
        subdict2 = phase2_hits[ip2]
        phase2_ips = subdict2['ip.dst'] + subdict2['ip.src']
        overlap = [i for i in internal_ips if i in phase2_ips]

这里唯一的新事物是overlap。通过使用列表生成器,我们可以找到所有重叠值(因此名称)。你可以称之为你想要的;只知道它将填充两者之间的所有常见值。 (您也可以使用它:公式基本上是[i for i in L1 if i in L2],其中L1L2都是列表。)

        if len(overlap) > 0:
            temp = (ip1, overlap, hits, color_list, ip2, [i for i in phase2_ips if i in overlap])
            matches.append(temp)

if语句确保phase1_hits内部或内部_附加IP与phase2_hits之间存在至少一个重叠。如果是这样,它将根据此信息填充元组(这是不可变的)。 (我选择了一个元组,因为它是不可变的,你知道它的结构,但你可以根据需要将它改成一个列表。)一旦填充,它就会被附加到matches列表。

完成两个循环后,你应该拥有你想要的东西。