2014-12-01 88 views
0

刚开始的时候,我知道这里有几个类似题目的问题,但没有一个是用这种方式解释的,问题范围也不一样。动态嵌套字典

我想动态添加嵌套字典条目。

用例如下: 我有一个监测网络的python脚本。为每个观察到的IP协议(tcp,udp,icmp)创建一个字典。然后,使用作为这些IP协议(80,443等)中的每一个的目的地端口(如果存在的话)的密钥来创建子字典(注意它是否将服务器端口视为源是无关紧要的或目的地,但通常服务器是目的地,所以我选择了HTTP和HTTPS作为示例)。对于这些目标端口中的每一个,创建与服务器IP相对应的密钥(例如,www.google.com的IP)。然后,另一个带有会话时间戳的字典首先被看作是密钥,而密钥的数据/值是客户端的IP。

但是,我想这需要随着时间的推移而被填充,因为在执行前或初始化之前我都没有数据。

输出将会考虑一个类似于:

{ 'icmp' : 
    { 'echo-request' : 
     { '<ip_of_www.google.com>' : 
      { '<timestamp>' : <some_client_ip> } 
     } 
     'echo-reply' : 
     { '<ip_of_www.google.com>' : 
      { '<timestamp>' : <some_client_ip> } 
     } 
    } 
    'tcp' : 
    { 
     '80' 
     { '<ip_of_www.google.com>' : 
      { '<timestamp>' : <some_client_ip> } 
      { '<timestamp>' : <some_client_ip> } 
     } 
     '443' 
     { '<ip_of_encrypted.google.com>' : 
      { '<timestamp>' : <some_client_ip> } 
      { '<timestamp>' : <some_client_ip> } 
      { '<timestamp>' : <some_client_ip> } 
      { '<timestamp>' : <some_client_ip> } 
     } 
    } 
} 

谢谢!

+0

1)随着时间的推移更新字典。 2)注意:作为密钥的时间戳没有太大意义。 3)你有一个无效的结构。你只能有一个键的值。 – 2014-12-01 22:09:02

+0

关于#1:这正是我所要求的... 关于#2:时间戳作为一个关键没有意义,这是一个夸张的例子 关于#3:我不知道什么你是这个意思。当然,只有一个键,但每个键的值可以是另一个字典(因此嵌套属性)。我在哪里展示/展示/期待/询问多值密钥? – Nick 2014-12-02 14:57:16

+0

你*必须*地址的第三点... – 2014-12-02 14:58:28

回答

3

给你:

def set_nested(dict, value, *path): 
    for level in path[:-1]: 
     dict = dict.setdefault(level, {}) 

    dict[path[-1]] = value 


d = {} 

set_nested(d, '127.0.0.1', 'icmp', 'echo', 'google.com', '1 dec 2014') 
set_nested(d, '127.0.0.1', 'icmp', 'echo', 'google.com', '2 dec 2014') 
set_nested(d, '127.0.0.1', 'icmp', 'echo', 'yahoo.com', '2 dec 2014') 
set_nested(d, 'error', 'udp') 

from pprint import pprint 
pprint(d) 

输出:

{'icmp': {'echo': {'google.com': {'1 dec 2014': '127.0.0.1', 
            '2 dec 2014': '127.0.0.1'}, 
        'yahoo.com': {'2 dec 2014': '127.0.0.1'}}}, 
'udp': 'error'} 

我也建议你看看jsontinydb,如果你想存储和查询结果。

+0

看起来不错。我会试试看看它是如何发展的。我之前并不熟悉吞噬其余元素的* path-style参数。这本身是值得+1 :) – Nick 2014-12-02 15:09:24

+0

当我运行你的代码,但添加一个更多的调用'set_nested'如下:'set_nested(d,'不是一个错误','udp','测试')' ,我最终在'pprint(d)'部分输出了相同的结果......你将如何修改以解决这个问题? – 2016-02-20 19:39:42