【问题标题】:Proper way to iterate Python dictionary and build new one迭代Python字典并构建新字典的正确方法
【发布时间】:2019-11-17 21:11:26
【问题描述】:

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

这是我的示例 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
                 }
             }
       }
 }

我特别想做的是以编程方式拉recordvalidlocationtags-ptags-sptags-pct,而不是做一堆尝试/除外。例如,要获得valid,我这样做:

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

现在,循环/重复顶级键/值已经很容易了,但是对于嵌套的键/值,我该如何完成呢?

【问题讨论】:

    标签: python python-3.x dmarc


    【解决方案1】:

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

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

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

    如果您希望它在找不到 key 的情况下返回其他内容,那么假设:

    jsonData.get("valid", "invalid_something_else")
    

    【讨论】:

      【解决方案2】:

      处理此问题的一种方法是利用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")

      【讨论】:

        【解决方案3】:

        简单:代替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', [])

        但如果您必须从那里深入了解,您可能需要遍历列表项。

        【讨论】:

        • 感谢您对此的意见。
        猜你喜欢
        • 1970-01-01
        • 2013-12-03
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2014-05-18
        • 1970-01-01
        • 2014-05-29
        • 1970-01-01
        相关资源
        最近更新 更多