Python搜索词典
样本数据:Python搜索词典,python,search,dictionary,Python,Search,Dictionary,样本数据: { 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
{
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 我确信这很简单,但我被讨厌的嵌套循环所困扰,需要一个比我的mud更清晰的简洁例程 谢谢你的帮助
谢谢。第一步。把字典翻过来
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索引)可以节省倒置现有词典的成本。为了好玩,下面介绍如何在一行理解中实现这一点
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'])
我以S.Lott的答案为基础,但有些不同。我使用集合删除重复项,并将搜索索引放在一起,以便更好地匹配您建议的答案
import collections
# data = your example data dictionary
index = collections.defaultdict(set)
for key in data:
datum = data[key]
for ip in datum['ip.dst']:
index[ip].update(datum['ip.src'])
for ip in datum['ip.src']:
index[ip].update(datum['ip.dst'])
print index['1.2.3.4']
print index['10.10.10.99']
返回:
set(['10.10.10.99', '10.1.1.5', '10.11.11.49'])
set(['1.2.3.4', '2.3.4.5'])
没有任何库(但S.Lott解决方案更短、更好,我喜欢它lol):
下面是一个列表,其中
数据
是您的字典,ip
是您要搜索的内容:
set(ips[ips[0]==ip]用于ips in((v['ip.dst'][0],v['ip.src'][0])用于v in data.itervalues())如果ips中有ip)
为什么键的值是'ip.dst'
和'ip.src'
列表?它们可以有多个值吗?不,它们不能有多个值。为什么会这样?这就是另一个开发人员创建它的方式。处理字典似乎有点痛苦,为什么不使用对象?我认为这是他需要解析的传统格式…感谢您提到defaultdict。。。最近我很少在python中学习到如此有用的新东西。想想所有的时候,我用我自己的“ListDict”类来代替…是的,很抱歉,关于列表中显示IP的源数据,各位,但我无法控制它。源数据在IP.src和.dst中永远不会有一个以上的IP。这里有一个略短的替代方法:在[('IP.src','IP.dst'),('IP.dst','IP.src')中为a设置[v[a][0],在[('IP.src','IP.src')]中为v设置my_dict.values(),如果v[b]==[search_IP]])
from functools import partial
def search_row(results, ip, row):
if row['ip.dst'][0] == ip:
results.add(row['ip.src'][0])
if row['ip.src'][0] == ip:
results.add(row['ip.dst'][0])
def search(ip, data):
results = set()
aggregator = partial(search_row, results, ip)
map(aggregator, data.values())
return results
print search('1.2.3.4', data)
print search('10.10.10.99', data)
x={
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']}
}
y=[(i['ip.dst'],i['ip.src']) for i in x.values()]
a,b=zip(*y)
#Looking for
lf=['1.2.3.4']
ips=[]
i=0
for ipsrc in a:
if ipsrc == lf:
ips.append(b[i])
i+=1
i=0
for ipdst in b:
if ipdst == lf:
ips.append(a[i])
i+=1
ips=set(ips)
print(ips)