Python - 查找字典
示例数据:
{
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 来索引),就能省去反转已有字典的时间和成本。