【问题标题】:Dynamic nested dictionaries动态嵌套字典
【发布时间】:2014-12-01 22:04:45
【问题描述】:

刚开始,我知道这里有几个标题相似的问题,但没有一个是这样解释的,问题的范围也不相同。

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

用例是这样的: 我有一个监控网络的 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> }
       }
   }
}

谢谢!

【问题讨论】:

  • 1) 随着时间的推移更新字典。 2)注意:时间戳作为键没有多大意义。 3)你有一个无效的结构。一个键只能有一个值。
  • 关于#1:这正是我所要求的......关于#2:作为键的时间戳不一定有意义,这是一个夸张的例子关于#3:我'我不确定你的意思。当然只有一个键,但每个键的值可以是另一个字典(因此嵌套属性)。我在哪里展示/展示/期望/询问多值键?
  • 你必须解决第三点...
  • 您是否在评论一个键值在一个实例中是一个字符串,而在另一个实例中是一个整数?除非你说的是那个场景,否则我不太明白你的意思。
  • { '&lt;timestamp&gt;' : &lt;some_client_ip&gt; } { '&lt;timestamp&gt;' : &lt;some_client_ip&gt; } ...

标签: python sockets dynamic dictionary nested


【解决方案1】:

你在这里:

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'}

如果您想存储和查询结果,我还建议您查看json 和tinydb。

【讨论】:

  • 看起来不错。我会试试这个,看看效果如何。我以前不熟悉吞噬其余元素的 *path 样式参数。这本身就值得 +1 :)
  • 当我运行您的代码时,但又添加了一个对set_nested 的调用,如下所示:set_nested(d, 'not-an-error', 'udp', 'test'),我最终在pprint(d) 部分得到相同的输出...您将如何修改解决这个问题?
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2018-06-02
  • 2021-06-21
  • 1970-01-01
  • 2018-09-15
  • 2022-01-15
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多