解析 JSON 对象的最有效方法 [重复]

Posted

技术标签:

【中文标题】解析 JSON 对象的最有效方法 [重复]【英文标题】:Most effective way to parse JSON Objects [duplicate] 【发布时间】:2021-08-20 12:27:01 【问题描述】:

我目前正在尝试访问 JSON 对象中的特定值,我正在使用 Try / except 语句成功地做到这一点。

由于我还在学习 Python,我想知道是否有更有效的方法来实现这一点。我经常发现,对于不同的 JSON 数据集,键/值对会移动,我必须在我的代码中手动更改索引值,从 [0] [1] [2] 或 [3]

JSON 数据:


 "notifications": [
  
   "timestamp": "1619847600000000000",
   "path_elements": [
    "Devices",
    "NME39488200",
    "versioned-data",
    "interfaces",
    "data",
    "Ethernet1",
    "aggregate",
    "rates",
    "1m"
   ],
   "updates": 
    "alignmentErrors": 
     "key": "alignmentErrors",
     "value": 
      "avg": 
       "float": 0
      ,
      "max": 
       "float": 0
      ,
      "min": 
       "float": 0
      ,
      "stddev": 
       "float": 0
      ,
      "weight": 
       "float": 1
      
     
    ,
    "fcsErrors": 
     "key": "fcsErrors",
     "value": 
      "avg": 
       "float": 0
      ,
      "max": 
       "float": 0
      ,
      "min": 
       "float": 0
      ,
      "stddev": 
       "float": 0
      ,
      "weight": 
       "float": 1
      
     
    ,
    "frameTooLongs": 
     "key": "frameTooLongs",
     "value": 
      "avg": 
       "float": 0
      ,
      "max": 
       "float": 0
      ,
      "min": 
       "float": 0
      ,
      "stddev": 
       "float": 0
      ,
      "weight": 
       "float": 1
      
     
    ,
    "frameTooShorts": 
     "key": "frameTooShorts",
     "value": 
      "avg": 
       "float": 0
      ,
      "max": 
       "float": 0
      ,
      "min": 
       "float": 0
      ,
      "stddev": 
       "float": 0
      ,
      "weight": 
       "float": 1
      
     
    ,
    "inErrors": 
     "key": "inErrors",
     "value": 
      "avg": 
       "float": 0
      ,
      "max": 
       "float": 0
      ,
      "min": 
       "float": 0
      ,
      "stddev": 
       "float": 0
      ,
      "weight": 
       "float": 1
      
     
    ,
    "outDiscards": 
     "key": "outDiscards",
     "value": 
      "avg": 
       "float": 0
      ,
      "max": 
       "float": 0
      ,
      "min": 
       "float": 0
      ,
      "stddev": 
       "float": 0
      ,
      "weight": 
       "float": 1
      
     
    ,
    "outErrors": 
     "key": "outErrors",
     "value": 
      "avg": 
       "float": 0
      ,
      "max": 
       "float": 0
      ,
      "min": 
       "float": 0
      ,
      "stddev": 
       "float": 0
      ,
      "weight": 
       "float": 1
      
     
    ,
    "symbolErrors": 
     "key": "symbolErrors",
     "value": 
      "avg": 
       "float": 0
      ,
      "max": 
       "float": 0
      ,
      "min": 
       "float": 0
      ,
      "stddev": 
       "float": 0
      ,
      "weight": 
       "float": 1
      
     
    
   
  ,
  
   "timestamp": "1622629140000000000",
   "path_elements": [
    "Devices",
    "NME39488200",
    "versioned-data",
    "interfaces",
    "data",
    "Ethernet11",
    "aggregate",
    "rates",
    "1m"
   ],
   "updates": 
    "inMulticastPkts": 
     "key": "inMulticastPkts",
     "value": 
      "avg": 
       "float": 0.03333333333333334
      ,
      "max": 
       "float": 0.1
      ,
      "min": 
       "float": 0
      ,
      "stddev": 
       "float": 0.047140452079103175
      ,
      "weight": 
       "float": 1
      
     
    ,
    "inOctets": 
     "key": "inOctets",
     "value": 
      "avg": 
       "float": 269348.4166666667
      ,
      "max": 
       "float": 341898.5
      ,
      "min": 
       "float": 223613.3
      ,
      "stddev": 
       "float": 45132.897905054306
      ,
      "weight": 
       "float": 0.9999999999999999
      
     
    ,
    "inUcastPkts": 
     "key": "inUcastPkts",
     "value": 
      "avg": 
       "float": 300.3333333333333
      ,
      "max": 
       "float": 364
      ,
      "min": 
       "float": 258.8
      ,
      "stddev": 
       "float": 44.179847089921985
      ,
      "weight": 
       "float": 0.9999999999999999
      
     
    ,
    "outMulticastPkts": 
     "key": "outMulticastPkts",
     "value": 
      "avg": 
       "float": 0.03333333333333334
      ,
      "max": 
       "float": 0.1
      ,
      "min": 
       "float": 0
      ,
      "stddev": 
       "float": 0.047140452079103175
      ,
      "weight": 
       "float": 0.9999999999999999
      
     
    ,
    "outOctets": 
     "key": "outOctets",
     "value": 
      "avg": 
       "float": 28700.35
      ,
      "max": 
       "float": 42799.9
      ,
      "min": 
       "float": 17571.2
      ,
      "stddev": 
       "float": 9737.234046475074
      ,
      "weight": 
       "float": 0.9999999999999999
      
     
    ,
    "outUcastPkts": 
     "key": "outUcastPkts",
     "value": 
      "avg": 
       "float": 196.13333333333333
      ,
      "max": 
       "float": 237
      ,
      "min": 
       "float": 164.4
      ,
      "stddev": 
       "float": 28.93957305989306
      ,
      "weight": 
       "float": 0.9999999999999999
      
     
    
   
  ,
  
   "timestamp": "1620649440000000000",
   "path_elements": [
    "Devices",
    "NME39488200",
    "versioned-data",
    "interfaces",
    "data",
    "Ethernet11",
    "aggregate",
    "rates",
    "1m"
   ],
   "updates": 
    "inDiscards": 
     "key": "inDiscards",
     "value": 
      "avg": 
       "float": 0
      ,
      "max": 
       "float": 0
      ,
      "min": 
       "float": 0
      ,
      "stddev": 
       "float": 0
      ,
      "weight": 
       "float": 1
      
     
    
   
  ,
  
   "timestamp": "1621745580000000000",
   "path_elements": [
    "Devices",
    "JPE13031399",
    "versioned-data",
    "interfaces",
    "data",
    "Ethernet11",
    "aggregate",
    "rates",
    "1m"
   ],
   "updates": 
    "inBroadcastPkts": 
     "key": "inBroadcastPkts",
     "value": 
      "avg": 
       "float": 0
      ,
      "max": 
       "float": 0
      ,
      "min": 
       "float": 0
      ,
      "stddev": 
       "float": 0
      ,
      "weight": 
       "float": 1
      
     
    ,
    "outBroadcastPkts": 
     "key": "outBroadcastPkts",
     "value": 
      "avg": 
       "float": 0
      ,
      "max": 
       "float": 0
      ,
      "min": 
       "float": 0
      ,
      "stddev": 
       "float": 0
      ,
      "weight": 
       "float": 1
      
     
    
   
  
 ]

我从多个 URL 获取 JSON 数据。我用来从 Key: 'InDiscards' 或 'OutDiscards' 中提取值 'Avg' 的代码如下:

for url in URLs:
    JSONdata = requests.get(url, cookies=cookies, verify=False).json()
    JSONkey = JSONdata["notifications"]
    name = JSONkey[0]["path_elements"][1]
    interface = JSONkey[0]["path_elements"][5]
    try:
        outDiscards = JSONkey[0]["updates"]["outDiscards"]["value"]["avg"]["float"]
    except KeyError:
        outDiscards = JSONkey[2]["updates"]["outDiscards"]["value"]["avg"]["float"]
    try:
        inDiscards = JSONkey[0]["updates"]["inDiscards"]["value"]["avg"]["float"]
    except KeyError:
        inDiscards = JSONkey[2]["updates"]["inDiscards"]["value"]["avg"]["float"]

我的理解是我们检查 index [0] 的 OutDiscards (或 InDiscards) 的平均值,如果我们找不到值,我们然后检查 index [2] ,但是肯定有更好的方法鉴于有时索引可能是 1/3/4/5 等,因此实现这一点......

【问题讨论】:

这能回答你的问题吗? How to convert JSON data into a Python object 【参考方案1】:

我建议使用 for 循环进行搜索。

首先初始化您的变量,我使用None,以便稍后确定我的搜索例程是否找到了一些东西

outDiscards = None
inDiscards = None

然后遍历通知列表中的所有元素

for notification in JSONdata["notifications"]:

仅在尚未找到该值时尝试访问该值

    if outDiscards is None:

尝试访问该值并忽略 KeyError

        try:
            outDiscards = notification["updates"]["outDiscards"]["value"]["avg"]["float"]
        except KeyError:
            pass
    if inDiscards is None:
        try:
            inDiscards = notification["updates"]["inDiscards"]["value"]["avg"]["float"]
        except KeyError:
            pass

在搜索例程之后应该有 outDiscards 和 inDiscards 中的值,您可以使用 if outDiscards is not None 进行测试

print(outDiscards)
print(inDiscards)

【讨论】:

这很好用,但是我不明白为什么,我自己也无法找到解决方案,能否解释一下为什么会这样? 你需要什么解释?我应该澄清 JSONdata["notifications"] 中的通知吗? 关于=none,然后在那个变量上循环 我编辑了我的答案以澄清

以上是关于解析 JSON 对象的最有效方法 [重复]的主要内容,如果未能解决你的问题,请参考以下文章

识别和删除数组中重复项的最有效方法是啥?

使用 JSON 对象解析和处理大文件的更有效方法

解析 JSON 给出“意外的令牌 o”错误 [重复]

使用 Perl 检查数据数组中重复项的最有效方法是啥?

从多维数组中删除数组的最有效方法[重复]

创建初始重复数据的二维字符串数组的最有效方法是啥?