周凯,个人博客

  • 前端
  • 嵌入式
  • 工具
  • 后端
  • 随笔
个人记录
  1. 首页
  2. python
  3. 正文

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

2023年 12月 1日 1096点热度 0人点赞 0条评论
  • 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
    def init():
    load_data = {}
    with open("world-history.json", 'r') as f:
        content = f.read()
        load_data = json.loads(content, object_pairs_hook=obj_pairs_hook)
    
        with open("world-history-new.json", 'w') as f2:
            b = json.dumps(load_data["result"]["event"])
            f2.write(b)
            pass
    if __name__ == '__main__':
    init()

🎯 拓展阅读提示

本文涉及的内容已同步至公众号后台,我会在那里分享更多深度内容和实用技巧

→ 点击关注:一行梦境

公众号二维码
本作品采用 知识共享署名 4.0 国际许可协议 进行许可
标签: 暂无
最后更新:2023年 12月 1日

周凯

这个人很懒,什么都没留下

打赏 点赞
< 上一篇
下一篇 >

文章评论

razz evil exclaim smile redface biggrin eek confused idea lol mad twisted rolleyes wink cool arrow neutral cry mrgreen drooling persevering
取消回复

COPYRIGHT © 2022-现在 周凯,个人博客. ALL RIGHTS RESERVED.

Theme Kratos Made By Seaton Jiang

蒙ICP备18004897号