【问题标题】:compare two json objects and remove the element and then compare resultant json to other json file比较两个 json 对象并删除元素,然后将结果 json 与其他 json 文件进行比较
【发布时间】:2017-10-27 23:02:07
【问题描述】:

Python 新手:

默认.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'
    },
} ]

我有一个 default.json 和 remote .json。我想要实现的任务是 从 删除所有 json 元素 strong>remote.json 的 remote.json 的值与 default.json 匹配的对象。例如由于 name 的键、值default.json 中的 :{provider=""} 匹配 remote.json 中的 name:{provider=""} .它应该从 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.我不知道如何从 default 获取密钥、值并将其与 file 进行比较?任何帮助将不胜感激。

我需要从 remote.json 中删除元素的原因是因为我需要将生成的 json 与其他 json 文件“local.json”进行比较。如果我不删除键,值“”或 null 或 None那么 remote.json 和 local.json 之间的比较永远不会相等。

2.有没有更好的办法解决这个问题?

local.json

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

【问题讨论】:

  • 顺便说一句,您的 JSON 无效:None 不是 null 和 False 不是 false
  • 子词典也应该被过滤?
  • 请添加过滤后的远程 JSON 示例
  • 在您的示例中添加了假设过滤子词典(如 'test')的修复

标签: python json parsing dictionary


【解决方案1】:

JSON 示例存在一些问题,因为 None 和 False 不是有效的 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"}}]

【讨论】:

  • 感谢您的详细回答。filtered_remote_json 不应该包含 None 或 False 或 "" 值的键。我应该如何重构列表理解?跨度>
  • @immrsteel:所以你也需要过滤子字典?
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2014-03-02
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多