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

Python中jsonpath-ng过滤与值提取问题及使用咨询

语法与原理说明

1. 学习路径

jsonpath-ng是JSONPath规范的Python原生实现,核心逻辑是将JSONPath表达式解析为抽象语法树,再递归遍历目标JSON对象完成节点匹配。最准确的学习材料是库自带的单元测试用例,覆盖了所有语法的实现细节和使用示例,比零散的第三方资料更贴合实际使用。

2. 两种访问格式的区分

  • 点语法(jpath.key):仅适用于属性名是合法标识符(不含特殊字符、空格、不以数字开头)的场景,all()是类方法,用于返回当前节点下的所有子节点集合
  • 方括号语法(jpath[key]):适用于属性名含特殊字符、属性名是变量、访问数组索引的场景,[*]是通配符,用于匹配数组的所有元素或对象的所有子属性
    示例:你代码中动态拼接ID的路径units.'{curr_id}'可以写为更规范的units[{curr_id}],无需额外加单引号包裹变量。

3. 过滤从句语法

过滤从句格式为[? 过滤表达式],直接追加在需要过滤的节点后:

  • 用@指代当前正在匹配的节点
  • 支持==/!=/>/<等比较运算符,&&/||逻辑运算符
    示例1:过滤所有已激活的技能:Abilities[?Activated == true]
    示例2:过滤GearTier大于等于3的升级项:Levels[?Requirements.GearTier >= 3]

代码优化方案

首先定义道具ID到位置的映射,避免硬编码判断:

# 道具ID对应req字段的位置索引,依次对应req2到req5及预留位
ITEM_POS_MAP = {
    133: 0,
    13: 1,
    3883066061505188: 2,
    6221535176831871: 3,
    4010306196179359: 4
}

优化后的遍历逻辑,减少冗余JSONPath解析,逻辑更清晰:

from jsonpath_ng import parse

total = []
# 一次匹配所有unit节点,无需单独查询ID
unit_expr = parse("units.*")
for unit_match in unit_expr.find(data):
    unit_data = unit_match.value
    toon_id = unit_data["ID"]
    # 遍历当前角色的所有技能
    for ability in unit_data.get("Abilities", []):
        ability_id = ability.get("ID", "")
        ability_name = ability.get("NameKey", "")
        ability_type = ability.get("AbilityType", "")
        # 遍历技能的所有升级等级
        for level in ability.get("Levels", []):
            # 拼接target字段
            target_list = []
            if level.get("TargetSelf"):
                target_list.append("Self")
            if level.get("TargetAlly"):
                target_list.append("Ally")
            if level.get("TargetEnemy"):
                target_list.append("Enemy")
            target = ",".join(target_list)
            # 获取gear要求,缺省为0
            gear_req = level.get("Requirements", {}).get("GearTier", 0)
            # 初始化5个req字段均为0,自动统一长度
            req_list = [0] * 5
            recipe = level.get("Recipe")
            if recipe:
                for ingredient in recipe.get("Ingredients", []):
                    item_id = ingredient.get("ItemID")
                    count = ingredient.get("Count", 0)
                    if item_id in ITEM_POS_MAP:
                        req_list[ITEM_POS_MAP[item_id]] = count
            # 拼接完整行,总长度固定为11,无需手动对齐
            row = [toon_id, ability_id, ability_name, ability_type, target, gear_req] + req_list
            total.append(row)

优化点说明

  • 仅执行一次JSONPath解析,后续直接操作Python原生对象,性能远高于重复解析路径匹配
  • 所有字段取值用get方法加默认值,兼容字段缺失、值为null的场景
  • 提前初始化固定长度的req列表,无需手动补0对齐
  • 去掉冗余的临时变量,避免索引操作导致的数据错位

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.10.02 00:18:00