2014-09-10 159 views
1

我希望根據另一個JSON字典的鍵和值在一個JSON字典中刪除鍵和值。從某種意義上說,我正在尋找一種「減法」。比方說,我有JSON字典ab如何基於另一個字典刪除字典的鍵和值?

a = { 
    "my_app": 
     { 
     "environment_variables": 
      { 
      "SOME_ENV_VAR": 
       [ 
       "/tmp", 
       "tmp2" 
       ] 
      }, 

     "variables": 
      { "my_var": "1", 
      "my_other_var": "2" 
      } 
     } 
    } 

b = { 
     "my_app": 
     { 
     "environment_variables": 
      { 
      "SOME_ENV_VAR": 
       [ 
       "/tmp" 
       ] 
      }, 

     "variables": 
      { "my_var": "1" } 
     } 
    } 

想象一下,你可以做a - b = c其中c看起來是這樣的:

c = { 
     "my_app": 
     { 
     "environment_variables": 
      { 
      "SOME_ENV_VAR": 
       [ 
       "/tmp2" 
       ] 
      }, 

     "variables": 
      { "my_other_var": "2" } 
     } 
    } 

如何才能做到這一點?

+0

在關鍵'' 「變量」 下存儲的內部字典''在你的字典中你似乎覆蓋關鍵'' 「my_var」''的價值。值「'1」「'不出現在a或b中。這是否按預期工作?你如何在你的字典c中獲得值''「1」''? – Nras 2014-09-10 12:04:33

+0

我的意圖是在某種意義上執行「減法」。所以想象一下我想做一個b。由於具有值「1」的'「my_var」'實際上不在'b'中,因此我希望保持它原樣 - 導致c在其字典中仍保留該鍵和該值。 – fredrik 2014-09-10 12:07:54

+1

您的字典中不能有兩個具有相同鍵的記錄。請修正'a ['變量']'。 – soupault 2014-09-10 12:14:40

回答

0

下做你所需要的:

def subtract(a, b): 
     result = {} 

     for key, value in a.items(): 
      if key not in b or b[key] != value: 
       if not isinstance(value, dict): 
        if isinstance(value, list): 
         result[key] = [item for item in value if item not in b[key]] 
        else: 
         result[key] = value 
        continue 

       inner_dict = subtract(value, b[key]) 
       if len(inner_dict) > 0: 
        result[key] = inner_dict 

     return result 

它檢查是否都keyvalue都存在。它可能del項目,但我認爲要更好地返回一個新的字典與所需的數據,而不是修改原來的。

c = subtract(a, b) 

UPDATE

我剛剛更新了由問題提供的數據的最新版本。現在它也「減去」列表值。

更新2

工作例如:ipython notebook

+0

當我用我的字典運行你的代碼時,我得到'KeyError:u'variables''。我試圖找出如何修改你的代碼,以允許這... – fredrik 2014-09-10 13:25:56

+0

它適用於我的Python 2.7與給定的'a'和'b'字典...你可以給更多的信息,並在上實際使用的數據? – rhlobo 2014-09-10 16:15:27

+0

有趣的是,如果字典在調用'b [key]'時不包含該鍵,就會發生'KeyError'。正如在'if'語句中檢查的那樣,我猜想你使用的縮進與上面的不一樣。你能檢查它嗎? – rhlobo 2014-09-10 16:23:43

0

你能做到這一點的方法是:

  1. 創建的副本a - >c;
  2. 迭代key, value對內b;
  3. 檢查是否爲同一top keys你有相同的inner keys and valuesc將其刪除;
  4. empty values刪除keys

你應該修改代碼,如果你的情況會有所不同(不是dict(dict)等)。


print(A) 
print(B) 
C = A.copy() 

# INFO: Suppose your max depth is as follows: "A = dict(key:dict(), ...)" 
for k0, v0 in B.items(): 
    # Look for similiar outer keys (check if 'vars' or 'env_vars' in A) 
    if k0 in C: 
     # Look for similiar inner (keys, values) 
     for k1, v1 in v0.items(): 
      # If we have e.g. 'my_var' in B and in C and values are the same 
      if k1 in C[k0] and v1 == C[k0][k1]: 
       del C[k0][k1] 
     # Remove empty 'vars', 'env_vars' 
     if not C[k0]: 
      del C[k0] 

print(C) 

{'environment_variables': {'SOME_ENV_VAR': ['/tmp']}, 
'variables': {'my_var': '2', 'someones_var': '1'}} 

{'environment_variables': {'SOME_ENV_VAR': ['/tmp']}, 
'variables': {'my_var': '2'}} 

{'variables': {'someones_var': '1'}} 
相關問題