簡體   English   中英

使用不同級別的可合並鍵合並Python嵌套字典

[英]Merging Python nested dictionaries with mergeable keys on different levels

我花了一段時間尋找這個問題的解決方案,但是所有解決方案都假定可連接鍵在字典的同一嵌套級別中。

簡而言之,有以下兩個指示:

dict1 = {'Head': 
            {'Face': 
                {'Eyes': 
                    {'Eyebrows': {}, 
                     'Eyelids': 
                        {'Eyelashes': {}
                        }
                    }, 
                 'Nose': {}, 
                 'Mouth': {}
                }
            }
        }
dict2 = {'Eyes': 
            {'Eyebrows': {}, 
             'Eyelids': 
                {'Eyelashes': {}
                }
            }
        }

我想要以下內容:

dict3 = {'Head': 
            {'Face': 
                {'Eyes': 
                    {'Eyebrows': {}, 
                     'Eyelids': 
                        {'Eyelashes': {}
                        }
                    },         
                 'Nose': {}, 
                 'Mouth': {}
                }
            }
        }

如您所見,在這個小示例中,鍵“ Eyes”應該是合並點,並且在dict1中位於樹的第三層,在dict2中位於樹的第三層。 字典的所有鍵/值可能有重疊(在不同級別,例如在“眼睛”情況下),或者根本沒有重疊,但是我也要避免重復。

關鍵是,我會發現一個字典已經包含在另一個字典中,或者它們根本不會重疊。 我試圖基於術語搜索(純字符串搜索)“修剪”僅保留某些節點的巨型樹。 問題在於某些節點(以及派生的更深的節點)可能包括其他一些節點,但有時它們可​​能根本不重合。 可以將它視為您身體上的一棵樹/嵌套字典。 您可以搜索“細胞”,找到一個稱為“血細胞”的大節點,其中包括“凝結細胞”,“轉運細胞”或“保護性細胞”等其他節點。 同樣,在主樹的另一個分支中,您可能會發現例如“骨細胞”。 所有這些都將在搜索中被檢索,其中一些可能包括其他(“凝血”,“運輸”或“保護性”將在“血細胞”內),但另一些可能與該樹分離(“骨細胞” )。 我希望它們位於同一全局嵌套樹中。

在這種情況下,如何合並幾個詞典? 提前致謝!

如果您不知道它們相交的級別,則必須執行深度優先搜索樹之類的操作來確認字典2不在字典1中,然后將它們都添加到頂層。

找到級別,然后執行您的詞典合並。

您可以使用一個簡單的遞歸函數來更新字典(節點:我在輸入中的空字典中添加了鍵值對,以反映以下代碼所進行的實際更改):

d = {'Head': {'Face': {'Eyes': {'Eyebrows': {}, 'Eyelids': {'Eyelashes': {}}}, 'Nose': {}, 'Mouth': {}}}}
dict2 = {'Eyes': 
           {'Eyebrows': {"color":'brown'}, 
             'Eyelids': 
            {'Eyelashes': {"type":"long", "color":"black"}
            }
        }
 }
def update_dict(d, update_with):
   if not any(i in update_with for i in d):
     return {a:update_dict(b, update_with) if isinstance(b, dict) else b for a, b in d.items()}
   return {a:update_dict(b, update_with if a not in update_with else update_with[a]) if isinstance(b, dict) and b \
       else update_with.get(a, b) for a, b in d.items()}

import json
print(json.dumps(update_dict(d, dict2), indent=4))

輸出:

{
"Head": {
    "Face": {
        "Eyes": {
            "Eyebrows": {
                "color": "brown"
            },
            "Eyelids": {
                "Eyelashes": {
                    "type": "long",
                    "color": "black"
                }
             }
         },
         "Nose": {},
         "Mouth": {}
     }
  }
}

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM