0

我试图找到一种有说服力的方法来检查字典中是否存在某些键并使用它们来构建一个新键。

这是我的示例 json:

 "dmarc": {
    "record": "v=DMARC1; p=none; rua=mailto:dmarc.spc@test.domain; adkim=s; aspf=s",
    "valid": true,
    "location": "test.domain",
    "warnings": [
                "DMARC record at root of test.domain has no effect"
                ],
     "tags": {
            "v": {
                   "value": "DMARC1",
                   "explicit": true
                 },
            "p": {
                   "value": "none",
                   "explicit": true
                 },
            "rua": {
                   "value": [
                          {
                           "scheme": "mailto",
                           "address": "ssc.dmarc.spc@canada.ca",
                           "size_limit": null
                          }
                         ],
                   "explicit": true
                   },
            "adkim": {
                   "value": "s",
                   "explicit": true
                     },
            "aspf": {
                   "value": "s",
                   "explicit": true
                   },
            "fo": {
                   "value": [
                             "0"
                            ],
                   "explicit": false
                  },
           "pct": {
                   "value": 100,
                   "explicit": false
                  },
           "rf": {
                  "value": [
                            "afrf"
                           ],
                  "explicit": false
                 },
           "ri": {
                  "value": 86400,
                  "explicit": false
                 },
           "sp": {
                  "value": "none",
                  "explicit": false
                 }
             }
       }
 }

我特别想做的是 pull record, valid, location, tags-p, tags-sp, 和tags-pct以编程方式,而不是做一堆 try/excepts。例如,要获得valid,我会:

try:
    res_dict['valid'] = jsonData['valid']
except KeyError:
    res_dict['valid'] = None

现在,这很容易循环/重复顶级键/值,但是我将如何为嵌套的键/值完成此操作?

4

3 回答 3

2

不,您不需要try-except相同的块。您可以使用以下方法检查密钥是否存在:

if jsonData.get("valid"):
    res_dict["valid"] = jsonData.get("valid")

.get("key")方法返回给定的值key,如果存在于字典中。如果不是,那么它将返回 None (如果 get() 仅与一个参数一起使用)。

如果您希望它在找不到时返回其他内容,key则假设:

jsonData.get("valid", "invalid_something_else")
于 2019-11-17T21:15:08.257 回答
1

简单:而不是dict['key']使用

  • dict.get('key', {})对于所有不是叶子的节点,并且
  • dict.get('key', DEFAULT)对于叶子,DEFAULT你需要什么。

如果你省略DEFAULT并且'key'不存在,你会得到None. 见the docs

例如:

jsonData.get('record', "")    # empty string if no 'record' key
jsonData.get('valid', False)  # False if no 'valid' key
jsonData.get('location')      # None if no 'location'
jsonData.get('tags', {}).get('p')  # None if no 'tags' and/or no 'p'
jsonData.get('tags', {}).get('p', {})  # {} if no 'tags' and/or no 'p'
jsonData.get('tags', {}).get('p', {}).get('explicit', False)  # and so on

以上假设您不遍历列表(JSON 数组)。如果你这样做,你仍然可以使用

  • dict.get('key', [])

但是如果你必须从那里更深入地研究,你可能不得不遍历列表项。

于 2019-11-17T21:14:50.813 回答
1

处理此问题的一种方法是利用结果dict.keys可以被视为set. 请参阅以下代码。

my_keys = {'record', 'valid', 'location'} # you can add more here
new_dict = {}
available_keys = my_keys & jsonData.keys()
for key in available_keys:
    new_dict[key] = jsonData[key]

上面,我们在集合中定义了我们感兴趣的键my_keys。然后,我们通过获取字典中的键和我们感兴趣的键的交集来获取可用的键。实际上,这只会获取我们感兴趣的并且也在字典中定义的键。最后,我们只是遍历available_keys并构建新字典。

None但是,如果输入字典中不存在键,这不会将键设置为。为此,最好使用get其他答案中提到的方法,如下所示:

my_keys = ['record', 'valid', 'location'] # you can add more here
new_dict = {}
for key in my_keys:
    new_dict[key] = jsonData.get(key)

get方法允许我们尝试获取字典中键的值。如果未定义该键,则返回None. get您还可以通过向方法添加额外的参数来更改返回的默认值,如下所示new_dict[key] = jsonData.get(key, "some other default value")

于 2019-11-17T21:20:08.263 回答