2014-12-01 116 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