2017-05-27 51 views
0

Python的新手:比較兩個JSON對象和刪除的元素,然後所得的JSON比較其他JSON文件

Default.json

{ 
"name": { 
"provide": "" 
}, 
"test": { 
    "Fail": { 
    "centers": None, 
    "Nearest": 0 
    }, 
    "far": "", 
    "Meta": null, 
    "Only": false, 
    "Tags": null 
}, 
"Session": "", 
"conf": { 
    "check": "", 
    "Reg": "" 
}, 
"Token": "" 

}

Remote.json 

[ { 
    'name': { 
    'provide': '' 
    }, 
    'Name': 'abc', 
    'test': { 
    'Service': 'redis', 
    'Tags': [ 
     'stage' 
    ], 
    'Fail': { 
     'centers': None, 
     'Nearest': 3 
    }, 
    'Only': false, 
    'far': '', 
    'Meta': null 
    }, 
    'Token': '', 
    'Session': '', 

    'conf': { 
    'Reg': '', 
    'check': 'name_prefix_match' 
    }, 
} ] 

我有默認.json遠程.json。任務我試圖實現的是刪除所有的json元素remote.json爲誰remote.json的值匹配與自該密鑰的default.json。例如,名稱的值:從default.json {提供商=「」}名稱匹配:{供應商= 「」}remote.json。它應該得到remote.json

with open(remote.json) as f: 
with open(default.json) as m: 
    file=json.load(f) 
    default=json.load(m) 
    for i in xrange(len(file)): 
    for key,value in default.items(): 
     #default[key]=value 
     #a=filter(lambda x: x[""],file.keys()) 

1.I刪除我沒有得到這個想法這裏如何獲得密鑰,價值從默認並與文件比較?任何幫助,將不勝感激。

我需要從remote.json中刪除元素的原因是因爲我需要將生成的json與其他json文件「local.json」進行比較。如果我不刪除鍵值,值爲「」或null或沒有,那麼remote.json和local.json之間的比較永遠不會相等。

2.是否有更好的方法去解決這個問題?

本地。JSON

{ 
    "Name": "", 
    "conf": { 
    "check": "name_prefix_match", 
    }, 
    "test": { 
    "Service": "redis", 
    "Fail": { 
    "Near": 3 
    }, 
    "Tags": "" 
    } 
} 
+1

BTW您的JSON是無效的:'None'不是'null'和'FALSE'不'FALSE' –

+0

子詞典也應該被過濾? –

+0

請添加已過濾的遠程JSON示例 –

回答

2

有一些問題,因爲None & False JSON例子不是有效的JSON對象(等等都是single-quoted string literals),所以讓「假裝我們」已經已經被解析文件,並得到了類似

default_json = { 
    "name": { 
     "provide": "" 
    }, 
    "test": { 
     "Fail": { 
      "centers": None, 
      "Nearest": 0 
     }, 
     "far": "", 
     "Meta": None, 
     "Only": False, 
     "Tags": None 
    }, 
    "Session": "", 
    "conf": { 
     "check": "", 
     "Reg": "" 
    }, 
    "Token": "" 
} 

remote_json = [{ 
    "name": { 
     "provide": "" 
    }, 
    "Name": "abc", 
    "test": { 
     "Service": "redis", 
     "Tags": [ 
      "stage" 
     ], 
     "Fail": { 
      "centers": None, 
      "Nearest": 3 
     }, 
     "Only": False, 
     "far": "", 
     "Meta": None 
    }, 
    "Token": "", 
    "Session": "", 

    "conf": { 
     "Reg": "", 
     "check": "name_prefix_match" 
    }, 
}] 

假設remote.json是字典&列表它們中的每一個應該使用default.json被過濾掉:

filtered_remote_json = [dict(item 
          for item in dictionary.items() 
          if item not in default_json.items()) 
         for dictionary in remote_json] 

會給我們

filtered_remote_json == [{"Name": "abc", 
          "test": {"Service": "redis", "Tags": ["stage"], 
            "Fail": {"centers": None, 
              "Nearest": 3}, "Only": False, 
            "far": "", "Meta": None}, 
          "conf": {"Reg": "", 
            "check": "name_prefix_match"}}] 

編輯

如果我們需要過濾子字典爲好,那麼下一個有點討厭的效用函數應該幫助

def filter_defaults(json_object, default_json_object): 
    result = {} 
    for key, value in json_object.items(): 
     try: 
      default_value = default_json_object[key] 
     except KeyError: 
      # key not in defaults, adding to result 
      result[key] = value 
      continue 

     # we need to process sub-dictionaries as well 
     if isinstance(value, dict): 
      value = filter_defaults(value, default_value) 
      # we are not interested in empty filtered sub-dictionaries 
      if not value: 
       continue 
     # value should differ from default 
     elif value == default_value: 
      continue 

     result[key] = value 

    return result 

然後就寫

filtered_remote_json = [filter_defaults(dictionary, default_json) 
         for dictionary in remote_json] 

這會給我們

filtered_remote_json == [{"Name": "abc", 
          "test": {"Service": "redis", "Tags": ["stage"], 
            "Fail": {"Nearest": 3}}, 
          "conf": {"check": "name_prefix_match"}}] 
+0

感謝您的詳細解答。filtered_remote_json不應具有無或錯誤或「」在其中。我應該如何重構列表理解? – immrsteel

+0

@immrsteel:所以你還需要過濾子字典? –

+0

Azat Ibrakov謝謝 – immrsteel