You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何在Python 3.7中高效实现多键分组的JSON转换?

更省心的Python扁平JSON转双层分组结构方案(适配你的需求)

看来你已经用itertools.groupby搞定了基础的转换,但面对更复杂的JSON转换需求,手写循环确实有点费精力——毕竟你更看重开发效率,而且数据集小完全不用纠结性能。刚好你提到Node.js的jsonata,Python里有完美对应工具,还有其他简化方案,我给你详细说说:

首选:用jsonata-python复刻你熟悉的jsonata体验

Python的jsonata包(安装时是jsonata-python)完全照搬了jsonata的语法,用声明式的表达式就能快速完成多层分组转换,不用再写一堆循环拼接字典,后续复杂转换改表达式就行,开发效率拉满。

步骤1:安装依赖

pip install jsonata-python

步骤2:一行表达式搞定转换

替代你原来两个函数的代码,只需要一段jsonata表达式:

import jsonata

def mapResearchSubTypeToResolutionCodesToSchema(qryResult):
    # 编写jsonata转换规则,完全贴合你的分组需求
    transform_expr = jsonata.compile("""
        // 第一层按rsch_sub_typ_cd分组
        $groupBy($, $v => $v.rsch_sub_typ_cd) ~> 
        // 把分组后的字典转成目标列表结构
        $map(($resolutions, $rsch_code) => {
            "researchSubTypeCode": $rsch_code,
            // 第二层按resl_cd分组,再组装resolutionTypes
            "resolutionTypes": $groupBy($resolutions, $v => $v.resl_cd) ~> 
                $map(($sub_resolutions, $resl_code) => {
                    "resolutionCode": $resl_code,
                    "resolutionSubTypeCodes": $sub_resolutions.sub_resl_cd
                })
        }) ~> 
        // 包裹成最终的顶层结构
        { "researchSubTypeToResolutionCodes": $ }
    """)
    return transform_expr.evaluate(qryResult)

if __name__ == '__main__':
    TEST_QRY_DATA = [
        {"rsch_sub_typ_cd": None, "resl_cd": 999991, "sub_resl_cd": 99992},
        {"rsch_sub_typ_cd": None, "resl_cd": 999991, "sub_resl_cd": 99993},
        {"rsch_sub_typ_cd": None, "resl_cd": 999995, "sub_resl_cd": 99996},
        {"rsch_sub_typ_cd": 33533, "resl_cd": 33726, "sub_resl_cd": 33730},
        {"rsch_sub_typ_cd": 33533, "resl_cd": 33726, "sub_resl_cd": 33731},
        {"rsch_sub_typ_cd": 33533, "resl_cd": 33726, "sub_resl_cd": 33732},
        {"rsch_sub_typ_cd": 33533, "resl_cd": 33726, "sub_resl_cd": 33774},
        {"rsch_sub_typ_cd": 33533, "resl_cd": 33727, "sub_resl_cd": 33730},
        {"rsch_sub_typ_cd": 33533, "resl_cd": 33727, "sub_resl_cd": 33731},
        {"rsch_sub_typ_cd": 33534, "resl_cd": 33726, "sub_resl_cd": 33730}
    ]
    result = mapResearchSubTypeToResolutionCodesToSchema(TEST_QRY_DATA)
    print(result)

运行这段代码会输出和你预期完全一致的结构,而且后续如果要调整分组规则或者字段映射,只需要修改jsonata表达式,不用动循环逻辑。

备选:用pandas简化代码(不用学新语法)

如果你不想引入新的工具,pandas虽然侧重数据分析,但处理这种分组转换也非常顺手,代码量比原来的itertools写法少很多:

import pandas as pd

def mapResearchSubTypeToResolutionCodesToSchema(qryResult):
    df = pd.DataFrame(qryResult)
    # 第一步:按两层分组,把sub_resl_cd聚合为列表
    grouped = df.groupby(['rsch_sub_typ_cd', 'resl_cd'])['sub_resl_cd'].agg(list).reset_index()
    # 第二步:按researchSubTypeCode分组,组装resolutionTypes列表
    final_df = grouped.groupby('rsch_sub_typ_cd').apply(
        lambda x: x.rename(columns={
            'resl_cd': 'resolutionCode',
            'sub_resl_cd': 'resolutionSubTypeCodes'
        })[['resolutionCode', 'resolutionSubTypeCodes']].to_dict('records')
    ).reset_index().rename(columns={
        'rsch_sub_typ_cd': 'researchSubTypeCode',
        0: 'resolutionTypes'
    })
    # 组装最终的JSON结构
    return {'researchSubTypeToResolutionCodes': final_df.to_dict('records')}

这个方案利用pandas的groupby和agg能力,省去了手动判断字典键是否存在、拼接列表的繁琐步骤,如果你已经熟悉pandas,上手零成本。

方案对比(帮你选合适的)

方案开发效率学习成本依赖情况适合场景
jsonata-python🌟🌟🌟🌟🌟中等(需要熟悉jsonata语法)第三方库复杂JSON转换、有Node.js jsonata经验
pandas🌟🌟🌟🌟低(熟悉pandas的话)第三方库同时需要数据处理+JSON转换
itertools.groupby🌟🌟🌟低内置库不能加额外依赖的场景

总结

如果你想复刻jsonata的开发体验,jsonata-python是最佳选择,声明式写法能让你快速搞定各种复杂JSON转换;如果已经在用pandas做数据处理,用pandas的方案也能大幅简化代码。两种方案都比原来的循环写法更省心,完全符合你追求开发效率的需求。

内容的提问来源于stack exchange,提问作者mojoken

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.05.12 05:24:54