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


    摘要

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

    不处理的情况

    例如:

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

    把上面的值写入到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)
    
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7

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

    {
        "key":["1","2","3"],
        "key2":"4"
    }
    
    • 1
    • 2
    • 3
    • 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.
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15

    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
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14

    然后在执行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)
    
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20

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

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

  • 相关阅读:
    无线渗透-WPA攻击
    最新 .NET 社区工具包, 推出MVVM 源代码生成器!
    [转]MySQL索引底层实现原理(此文个人觉得非常好收藏一下)
    股票业绩预测:实战 iwencai JS逆向 + 数据采集(20220803)
    我的MQTT操作类(M2Mqtt.Net)
    基于SSH开发学院图书馆管理系统 课程设计 大作业 毕业设计
    gin框架中使用websocket发送消息及群聊
    python中的并发编程-进程、线程2
    解决VSCode使用SSH远程连接时无法指定用户名的问题
    2023年上半年系统集成项目管理工程师什么时候报考?(附具体报名步骤)
  • 原文地址:https://blog.csdn.net/hhhhhhhhhhwwwwwwwwww/article/details/126746195