Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/python/342.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Python搜索词典_Python_Search_Dictionary - Fatal编程技术网

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)