Python使用JMESPath按嵌套属性过滤字典列表保留完整外层元素
JMESPath 过滤保留完整外层元素方案
直接在外层列表做过滤判断,不要先投影嵌套字段再筛选,核心是判断当前外层元素的fruits列表中是否存在type=orange的子项,符合条件就保留完整外层元素。
可用查询语句
# 写法1:利用JMESPath非空数组为真的规则,写法简洁 jmespath.search('[?fruits[?type == `orange`]]', my_list) # 写法2:显式判断匹配项长度,逻辑更直观,效果和写法1完全一致 jmespath.search('[?length(fruits[?type == `orange`]) > `0`]', my_list)
逻辑解释
- 外层
[? 过滤条件 ]是对外层列表逐元素做筛选,满足条件的元素会完整保留,不会只切出嵌套字段 - 内层的
fruits[?type ==orange]会取出当前元素下所有type=orange的水果项:有匹配时返回非空数组,JMESPath判定为真,保留当前外层元素;无匹配时返回空数组,判定为假,过滤掉该元素
原写法错误原因
你之前使用的[].fruits[?type==orange] []执行逻辑是:
- 遍历所有外层元素,投影取出每个元素的
fruits字段 - 在每个
fruits列表里筛选type=orange的子项 - 把多层筛选结果拍平成一维数组
整个流程没有对外层元素做过滤,而是直接提取了嵌套的匹配子项,自然拿不到完整的外层字典。
运行验证
传入你给出的测试列表执行上述查询,返回结果和预期完全一致:
[{'anotherfieds': 'aaa', 'fruits': [{'tastes': 'good', 'type': 'orange'}, {'tastes': 'bad', 'type': 'apple'}], 'name': 'A'}, {'differentfield': 'bbb', 'fruits': [{'tastes': 'so-so', 'type': 'orange'}, {'tastes': 'good', 'type': 'banana'}], 'name': 'B'}]
内容的提问来源于stack exchange,提问作者DominiCane
相关产品推荐
相关产品推荐

