递归搜索JSON对象后如何判断返回数据类型以实现正确遍历
递归搜索JSON对象后如何判断返回数据类型以实现正确遍历
首先得先搞清楚为什么会出现两种不同的遍历情况——这完全是由你匹配到的value本身的结构决定的:
- 当你搜索
Count时,每个匹配到的value都是单层列表(比如[0,1,2]),你的递归函数会直接把这个列表作为一个元素追加到search_result里,最终data的结构是[列表1, 列表2, 列表3,...],所以直接遍历data就能拿到每个Count对应的列表。 - 当你搜索
Channel1时,匹配到的value本身是嵌套列表([[21,22,23],[1,2,3],[4,5,6]]),函数同样把这个嵌套列表作为一个元素追加到结果里,最终data的结构就变成了[ [嵌套列表] ],所以你需要遍历data[0]才能拿到里面的子列表。
你之前用all(isinstance(i, list) for i in data)判断没用,是因为两种情况里data的元素都是列表——区别只在于列表的层级不同。
下面给你几个实用的解决方案,按需选择:
方案1:自动判断结构,动态选择遍历方式
可以写一个简单的辅助判断逻辑,根据返回结果的结构决定遍历层级:
def is_nested_list(item): # 判断一个列表是否是嵌套列表(即它的元素也是列表) return isinstance(item, list) and len(item) > 0 and isinstance(item[0], list) data = find_data(target_key, json_obj, []) if len(data) == 1 and is_nested_list(data[0]): # 情况1:结果是包含单个嵌套列表的列表,遍历嵌套列表 for item in data[0]: print(item) else: # 情况2:结果是多个单层列表的集合,直接遍历 for item in data: print(item)
这个逻辑适配你当前的JSON结构,如果后续有其他结构,也可以调整判断条件(比如如果data里有多个嵌套列表元素,就遍历每个元素的子列表)。
方案2:修改递归函数,统一结果结构
如果你希望不管匹配到的是单层还是嵌套列表,最终结果都是最外层的目标列表集合,可以修改递归函数里的追加逻辑:当匹配到的value是嵌套列表时,直接把它的子列表加入结果,而不是整个嵌套列表。修改后的关键代码如下:
if targetType == 'equal' and key == lookup_key: # 如果value是嵌套列表,就把里面的子列表逐个加入结果 if isinstance(value, list) and len(value) > 0 and isinstance(value[0], list): search_result.extend(value) else: search_result.append(value) elif targetType == 'regex' and pattern.search(key): if isinstance(value, list) and len(value) > 0 and isinstance(value[0], list): search_result.extend(value) else: search_result.append(value)
这样修改后,搜索Channel1得到的data会直接是[[21,22,23],[1,2,3],[4,5,6]],和搜索Count的结果结构一致,直接遍历data即可。
方案3:通用扁平化工具(按需使用)
如果你的需求是拿到最内层的元素(比如数字),可以写一个扁平化函数把所有嵌套层级展开:
def flatten(lst): result = [] for item in lst: if isinstance(item, list): result.extend(flatten(item)) else: result.append(item) return result data = find_data(target_key, json_obj, []) flattened_data = flatten(data) for num in flattened_data: print(num)
不过这个方案适用于需要提取最底层元素的场景,如果你需要保留列表层级就不用这个。
备注:内容来源于stack exchange,提问作者newdeveloper
相关产品推荐
相关产品推荐

