2014-09-10 155 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'}} 
相关问题