【问题标题】:manipulating json in python using recursion使用递归在python中操作json
【发布时间】:2017-09-25 17:49:07
【问题描述】:

全部,

我正在尝试通过以下方式对其进行格式化并更改某些 json 的外观:

1. flatten all of the fields lists
2. Then remove the fields lists and replace them with the name : flatten list

例子:

{
"name": "",
"fields": [{
        "name": "keys",
        "fields": [{
                "node-name": "0/0/CPU0"
            },
            {
                "interface-name": "TenGigE0/0/0/47"
            },
            {
                "device-id": "ASR9K-H1902.corp.cisco.com"
            }
        ]
    },
    {
        "name": "content",
        "fields": [{
            "name": "lldp-neighbor",
            "fields": [{
                    "receiving-interface-name": "TenGigE0/0/0/47"
                },
                {
                    "receiving-parent-interface-name": "Bundle-Ether403"
                },
                {
                    "device-id": "ASR9K-H1902.corp.cisco.com"
                },
                {
                    "chassis-id": "78ba.f975.a64f"
                },
                {
                    "port-id-detail": "Te0/1/0/4/0"
                },
                {
                    "header-version": 0
                },
                {
                    "hold-time": 120
                },
                {
                    "enabled-capabilities": "R"
                },
                {
                    "platform": ""
                }
            ]
        }]
    }
]
}

会变成:

{
"": [{

        "keys": [{
            "node-name": "0/0/CPU0",
            "interface-name": "TenGigE0/0/0/47",
            "device-id": "ASR9K-H1902.corp.cisco.com"
        }]
    },
    {
        "content": [{
            "lldp-neighbor": [{
                "receiving-interface-name": "TenGigE0/0/0/47",
                "receiving-parent-interface-name": "Bundle-Ether403",
                "device-id": "ASR9K-H1902.corp.cisco.com",
                "chassis-id": "78ba.f975.a64f",
                "port-id-detail": "Te0/1/0/4/0",
                "header-version": 0,
                "hold-time": 120,
                "enabled-capabilities": "R",
                "platform": ""
            }]
        }]
    }
]
}

我尝试了以下方法来使列表变平:

def _flatten_fields(self, fields_list):
        c = {}
        for b in [d for d in fields_list if bool(d)]:
                c.update(b)
        return c

这似乎可行,但我无法找到使用递归进入子级别的方法,我将所有扁平列表和名称保存到一个新字典中,有没有办法通过操纵原始来做到这一点字典?

【问题讨论】:

    标签: python json dictionary recursion


    【解决方案1】:

    这适用于您提供的示例:

    import json
    
    def flatten(data):
        result = dict()
        if isinstance(data, dict):
            if 'name' in data:
                name = data['name']
                result[name] = flatten(data['fields'])
            else:
                key = data.keys()[0]
                value = data.values()[0]
                result[key] = value
        else:
            for entry in data:
                result.update(flatten(entry))
        return result
    
    print json.dumps(flatten(data), indent=4)
    

    输出

    {
        "": {
            "keys": {
                "node-name": "0/0/CPU0", 
                "interface-name": "TenGigE0/0/0/47", 
                "device-id": "ASR9K-H1902.corp.cisco.com"
            }, 
            "content": {
                "lldp-neighbor": {
                    "receiving-interface-name": "TenGigE0/0/0/47", 
                    "receiving-parent-interface-name": "Bundle-Ether403", 
                    "header-version": 0, 
                    "port-id-detail": "Te0/1/0/4/0", 
                    "chassis-id": "78ba.f975.a64f", 
                    "platform": "", 
                    "device-id": "ASR9K-H1902.corp.cisco.com", 
                    "hold-time": 120, 
                    "enabled-capabilities": "R"
                }
            }
        }
    }
    

    它没有在您的预期输出中显示额外的list 层,但我认为您不需要这些。

    【讨论】:

      【解决方案2】:

      这适用于您提供的示例:

      def flatten_fields(fields_list):
      
          c = {}
          for item in fields_list:
              for key in item:
                  if key == "fields":
                      c[item["name"]] = flatten_fields(item["fields"])
                  elif key != "name":
                      c[key] = item[key]
                  break
      
          return [c]
      

      但它适用于字典列表,所以你应该像flatten_fields([data])[0] 这样称呼它。

      输出是:

      {
      "": [{
          "keys": [{
              "node-name": "0/0/CP0", 
              "interface-name": "TenGigE0/0/0/47", 
              "device-id": "ASR9K-H1902.corp.cisco.com"
              }], 
          "content": [{
              "lldp-neighbor": [{
                  "chassis-id": "78ba.f975.a64f", 
                  "receiving-parent-interface-name": "Bndle-Ether403", 
                  "enabled-capabilities": "R", 
                  "device-id": "ASR9K-H1902.corp.cisco.com", 
                  "hold-time": 120, 
                  "receiving-interface-name": "TenGigE0/0/0/47", 
                  "platform": "", 
                  "header-version": 0, 
                  "port-id-detail": "Te0/1/0/4/0"
                  }]
              }]
          }]
      }
      

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 2015-10-17
        • 1970-01-01
        • 2020-06-15
        • 2018-02-05
        • 2012-05-19
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多