python 如何解析含有重复key的json

举报
AI浩 发表于 2022/11/18 06:31:20 2022/11/18
【摘要】 @[toc] 摘要json里面的key默认是唯一,但是有些情况下json里面的key值并不唯一。比如我在分析WIFI协议的时候,如下图:这时候就需要解决key重复的问题。那么如何解决呢? 不处理的情况例如: {"key":"1", "key":"2", "key":"3", "key2":"4"}把上面的值写入到json文件中。如果不处理重复key的问题,输出结果会怎么样?代码如下:imp...

@[toc]

摘要

json里面的key默认是唯一,但是有些情况下json里面的key值并不唯一。比如我在分析WIFI协议的时候,如下图:
在这里插入图片描述
这时候就需要解决key重复的问题。那么如何解决呢?

不处理的情况

例如:

  {"key":"1", "key":"2", "key":"3", "key2":"4"}

把上面的值写入到json文件中。
在这里插入图片描述

如果不处理重复key的问题,输出结果会怎么样?
代码如下:

import json
json_list={"key": "1", "key": "2", "key": "3", "key2": "4"}

with open("4.json",'r',encoding='utf8') as fp:
    json_data = json.load(fp)
    print(json_data)

输出结果:
在这里插入图片描述
重复的key,程序默认只保留了最后一个值,这样显然不符合我们的需求。我们希望的结果是:

{
    "key":["1","2","3"],
    "key2":"4"
}

所以该怎么解决呢?

解决方法

首先来看一下解析函数load函数,如下:

def load(fp, *, cls=None, object_hook=None, parse_float=None,
        parse_int=None, parse_constant=None, object_pairs_hook=None, **kw):
    """Deserialize ``fp`` (a ``.read()``-supporting file-like object containing
    a JSON document) to a Python object.

    ``object_hook`` is an optional function that will be called with the
    result of any object literal decode (a ``dict``). The return value of
    ``object_hook`` will be used instead of the ``dict``. This feature
    can be used to implement custom decoders (e.g. JSON-RPC class hinting).

    ``object_pairs_hook`` is an optional function that will be called with the
    result of any object literal decoded with an ordered list of pairs.  The
    return value of ``object_pairs_hook`` will be used instead of the ``dict``.
    This feature can be used to implement custom decoders.  If ``object_hook``
    is also defined, the ``object_pairs_hook`` takes priority.

object_hook 是一个可选函数,将使用任何对象文字解码(dict)的结果调用。
object_hook 的返回值将被用来代替dict。 此功能可用于实现自定义解码器(例如 JSON-RPC 类提示)。
object_pairs_hook 是一个可选函数,将使用任何对象字面量的结果以有序的对列表解码的结果调用。
object_pairs_hook 的返回值将被用来代替dict。 此功能可用于实现自定义解码器。 如果还定义了“object_hook”,则“object_pairs_hook”优先。
object_pairs_hook是个回调函数,在解析json文本的时候会调用它并更改返回的结果。为了得到前述的结果,我们定义如下的hook函数:

def obj_pairs_hook(lst):
    result={}
    count={}
    for key,val in lst:
        if key in count:count[key]=1+count[key]
        else:count[key]=1
        if key in result:
            if count[key] > 2:
                result[key].append(val)
            else:
                result[key]=[result[key], val]
        else:
            result[key]=val
    return result

然后在执行load的时候加上这个函数。代码如下:

import json
def obj_pairs_hook(lst):
    result={}
    count={}
    for key,val in lst:
        if key in count:count[key]=1+count[key]
        else:count[key]=1
        if key in result:
            if count[key] > 2:
                result[key].append(val)
            else:
                result[key]=[result[key], val]
        else:
            result[key]=val
    return result

with open("4.json",'r',encoding='utf8') as fp:
    json_data = json.load(fp,object_pairs_hook=obj_pairs_hook)
    print(json_data)

输出结果:
在这里插入图片描述

参考文章:
https://blog.csdn.net/dahlwuyn/article/details/52293544

【版权声明】本文为华为云社区用户原创内容,转载时必须标注文章的来源(华为云社区)、文章链接、文章作者等基本信息, 否则作者和本社区有权追究责任。如果您发现本社区中有涉嫌抄袭的内容,欢迎发送邮件进行举报,并提供相关证据,一经查实,本社区将立刻删除涉嫌侵权内容,举报邮箱: cloudbbs@huaweicloud.com
  • 点赞
  • 收藏
  • 关注作者

评论(0

0/1000
抱歉,系统识别当前为高风险访问,暂不支持该操作

全部回复

上滑加载中

设置昵称

在此一键设置昵称,即可参与社区互动!

*长度不超过10个汉字或20个英文字符,设置后3个月内不可修改。

*长度不超过10个汉字或20个英文字符,设置后3个月内不可修改。