Python - 查找字典

2 投票
6 回答
706 浏览
提问于 2025-04-17 10:08

示例数据:

{
    10116079620: {'ip.dst': ['10.1.1.5'], 'ip.src': ['1.2.3.4'], 'category': ['Misc']}, 
    10116882439: {'ip.dst': ['1.2.3.4'], 'ip.src': ['10.1.1.5'], 'category': ['Misc']}, 
    10116080136: {'ip.dst': ['10.10.10.99'], 'ip.src': ['1.2.3.4'], 'category': ['Misc']}, 
    10116884490: {'ip.dst': ['10.10.10.99'], 'ip.src': ['2.3.4.5'], 'alias': ['www.example.com'], 'category': ['Misc']}, 
    10117039635: {'ip.dst': ['2.3.4.5'], 'ip.src': ['10.11.11.50'], 'alias': ['google.com'], 'category': ['Misc']}, 
    10118099993: {'ip.dst': ['1.2.3.4'], 'ip.src': ['10.11.11.49'], 'alias': ['www.google.com'], 'category': ['Misc']},
    10118083243: {'ip.dst': ['10.11.11.49'], 'ip.src': ['4.3.2.1'], 'alias': ['www.google.com'], 'category': ['Misc']}}
}

目标:

我的目标是用一个已知的值(IP地址)去查找这个示例字典,虽然不知道这个地址会出现在ip.dst还是ip.src里。一旦找到,我想把“相反的”IP地址写到一个新的列表里……如果搜索的地址在ip.src中找到,我就想记录ip.dst,反之亦然。

一个搜索的地址可能会出现多次,结果列表里不需要包含重复的地址。

如果搜索1.2.3.4,那么会捕获到以下地址:
* 10.1.1.5
* 10.10.10.99
* 10.11.11.49

如果搜索10.10.10.99,则会捕获到:
* 1.2.3.4
* 2.3.4.5

我相信这很简单,但我现在被复杂的嵌套循环困住了,需要一个比我现在的代码更简洁明了的解决方案。

感谢你的帮助。

谢谢。

6 个回答

1

这里有一个列表推导式,其中 data 是你的字典,而 ip 是你要查找的内容:

set(ips[ips[0]==ip] for ips in ((v['ip.dst'][0],v['ip.src'][0]) for v in data.itervalues()) if ip in ips)

2

为了好玩,这里有一种用一行代码实现的方法!

set([v['ip.dst'][0] for v in my_dict.values() if v['ip.src'] == [search_ip]] + [v['ip.src'][0] for v in my_dict.values() if v['ip.dst'] == [search_ip]])

输出结果:

>>>search_ip = '1.2.3.4'
>>>my_dict = {10116079620: {'ip.dst': ['10.1.1.5'], 'ip.src': ['1.2.3.4'], 'category': ['Misc']}, 10116882439: {'ip.dst': ['1.2.3.4'], 'ip.src': ['10.1.1.5'], 'category': ['Misc']}, 10116080136: {'ip.dst': ['10.10.10.99'], 'ip.src': ['1.2.3.4'], 'category': ['Misc']},  10116884490: {'ip.dst': ['10.10.10.99'], 'ip.src': ['2.3.4.5'], 'alias': ['www.example.com'], 'category': ['Misc']},  10117039635: {'ip.dst': ['2.3.4.5'], 'ip.src': ['10.11.11.50'], 'alias': ['google.com'], 'category': ['Misc']},  10118099993: {'ip.dst': ['1.2.3.4'], 'ip.src': ['10.11.11.49'], 'alias': ['www.google.com'], 'category': ['Misc']}, 10118083243: {'ip.dst': ['10.11.11.49'], 'ip.src': ['4.3.2.1'], 'alias': ['www.google.com'], 'category': ['Misc']}}
>>>set([v['ip.dst'][0] for v in my_dict.values() if v['ip.src'] == [search_ip]] + [v['ip.src'][0] for v in my_dict.values() if v['ip.dst'] == [search_ip]])
set(['10.1.1.5', '10.10.10.99', '10.11.11.49'])

>>>search_ip = '10.10.10.99'
>>>set([v['ip.dst'][0] for v in my_dict.values() if v['ip.src'] == [search_ip]] + [v['ip.src'][0] for v in my_dict.values() if v['ip.dst'] == [search_ip]])
set(['1.2.3.4', '2.3.4.5'])
5

第一步:反转字典。

dst= collections.defaultdict( list )
src= collections.defaultdict( list )
for k in original:
    for addr in original[k]['ip.dst']:
        dst[addr].append( k )
    for addr in original[k]['ip.src']:
        src[addr].append( k )

第二步:别去搜索,直接获取值。

你只需要快速检查一下 dst[addr]src[addr],就能知道原始字典中所有出现过的键。

反转字典是需要时间的。

如果一开始就建立更好的字典(比如用 ip.dst 和 ip.src 来索引),就能省去反转已有字典的时间和成本。

撰写回答