Python嵌套JSON子集检查函数遇列表时失效问题求助
递归检查嵌套字典(含列表)是否为子集
问题描述
将JSON转换为dict后,需要递归判断其中一个dict是否是另一个的子集:
- 若dict A有3个键、dict B有4个键,仅当A的所有键对应的值与B完全一致时返回True
- 检查需递归覆盖所有嵌套层级,包括列表内的字典、字典中的嵌套列表
原函数仅支持嵌套字典场景,遇到列表结构时失效。
原JSON示例(集合A)
{ "scheduleType": null, "scheduleOption": null, "timezone": null, "workflowHiveOnly": null, "hiveEngineVersion": null, "hivePoolName": null, "prestoPoolName": null, "maxActivationBehaviorRow": null, "allowActivationBehavior": null, "master": { "parentTableName": "null" }, "attributes": [], "behaviors": [ { "name": null, "parentTableName": null, "parentKey": null, "foreignKey": null, "matrixTableName": null, "allColumns": null, "defaultTimeFilterEnabled": null, "schema": [ { "name": null, "type": null, "parentColumn": null, "matrixColumnName": null }, { "name":null, "type":null, "parentColumn": null, "matrixColumnName":null } ] }, { "name": null, "parentTableName": null, "parentKey": null, "foreignKey": null, "matrixTableName": null, "allColumns": null, "defaultTimeFilterEnabled": null, "schema": [] }, { "name": null, "parentTableName": null, "parentKey": null, "foreignKey": null, "matrixTableName": null, "allColumns": null, "defaultTimeFilterEnabled": null, "schema": [ { "name": null, "type": null, "parentColumn": null, "matrixColumnName": null } ] } ] }
注:原JSON存在语法错误,已修正括号缺失、键名引号遗漏问题
原失效函数
def is_subset(a,b): def recursive_check_subset(a,b): for x in a: if not isinstance(a[x],dict): yield (x in b ) and (a[x] == b[x]) #return a bool else: if x in b: yield all(recursive_check_subset(a[x],b[x])) else: yield False return all(recursive_check_subset(a,b))
修正后的递归子集检查函数
def is_subset(a, b): # 处理基础数据类型:直接比较值是否相等 if not isinstance(a, (dict, list)): return a == b # 处理列表:检查a的每个元素都能在b中找到匹配的子集元素 if isinstance(a, list): b_copy = b.copy() for item_a in a: matched = False for idx, item_b in enumerate(b_copy): if is_subset(item_a, item_b): matched = True del b_copy[idx] break if not matched: return False return True # 处理字典:检查a的所有键都存在于b中,且对应值满足子集关系 if isinstance(a, dict): for key in a: if key not in b: return False if not is_subset(a[key], b[key]): return False return True
函数逻辑说明
- 基础类型处理:对于字符串、数字、
null等非容器类型,直接比较值是否相等,因为子集要求值完全匹配 - 列表处理:
- 遍历列表a的每个元素,在列表b中寻找至少一个满足子集关系的元素
- 找到匹配元素后从b的副本中删除,避免同一元素被重复匹配
- 若a中任意元素在b中找不到匹配,直接返回False
- 字典处理:遍历a的所有键,检查键是否存在于b中,且对应的值递归满足子集关系
测试示例
# 假设A是原完整dict,B是删除behaviors中第一个元素后的dict # 调用is_subset(B, A) 会返回True # 调用is_subset(A, B) 会返回False
内容的提问来源于stack exchange,提问作者Tommaso Masaracchio
相关产品推荐
相关产品推荐

