如何递归统计任意嵌套结构中含指定key的对象总数?
统计嵌套结构中含指定Key的对象数量
要统计任意嵌套结构中包含指定key的对象数量,最直接的方式是递归遍历整个数据结构,对每个元素进行判断:
实现思路
- 定义递归函数,接收待遍历的数据和目标key两个参数
- 初始化计数器为0
- 如果当前元素是字典(JSON对象):
- 检查是否包含目标key,是则计数器+1
- 递归遍历字典的所有值,累加计数
- 如果当前元素是列表/元组(JSON数组):
- 递归遍历列表中的每个元素,累加计数
- 其他类型(如字符串、数字等)直接返回0,不处理
Python 代码实现
def count_objects_with_key(data, target_key): count = 0 # 处理字典类型(JSON对象) if isinstance(data, dict): # 检查当前字典是否包含目标key if target_key in data: count += 1 # 递归遍历字典的所有值 for value in data.values(): count += count_objects_with_key(value, target_key) # 处理列表/元组类型(JSON数组) elif isinstance(data, (list, tuple)): for item in data: count += count_objects_with_key(item, target_key) # 其他数据类型直接跳过 return count
测试示例
用你提供的两组数据测试:
测试第一组数据
data1 = {"coins_series": [{"series": 1, "coins": [{"_id": "65c8c78845d911984d98f6be", "currency": "EUR", "reverse_id": "SVN200701001REG", "obverse_id": ["EUR199901001FRO"], "country": "SVN", "commemorative": False, "series": 1, "min_year": 2007, "denomination": 0.01, "diameter": 16.25, "thickness": 1.67, "weight": 2.3}, {"_id": "65c8c78845d911984d98f6bf", "currency": "EUR", "reverse_id": "SVN200701002REG", "obverse_id": ["EUR199901002FRO"], "country": "SVN", "commemorative": False, "series": 1, "min_year": 2007, "denomination": 0.02, "diameter": 18.75, "thickness": 1.67, "weight": 3.06}, {"_id": "65c8c78845d911984d98f6c0", "currency": "EUR", "reverse_id": "SVN200701005REG", "obverse_id": ["EUR199901005FRO"], "country": "SVN", "commemorative": False, "series": 1, "min_year": 2007, "denomination": 0.05, "diameter": 21.25, "thickness": 1.67, "weight": 3.92}, {"_id": "65c8c78845d911984d98f6c1", "currency": "EUR", "reverse_id": "SVN200701010REG", "obverse_id": ["EUR200702010FRO"], "country": "SVN", "commemorative": False, "series": 1, "min_year": 2007, "denomination": 0.1, "diameter": 19.75, "thickness": 1.93, "weight": 4.1}, {"_id": "65c8c78845d911984d98f6c2", "currency": "EUR", "reverse_id": "SVN200701020REG", "obverse_id": ["EUR200702020FRO"], "country": "SVN", "commemorative": False, "series": 1, "min_year": 2007, "denomination": 0.2, "diameter": 22.25, "thickness": 2.14, "weight": 5.74}, {"_id": "65c8c78845d911984d98f6c3", "currency": "EUR", "reverse_id": "SVN200701050REG", "obverse_id": ["EUR200702050FRO"], "country": "SVN", "commemorative": False, "series": 1, "min_year": 2007, "denomination": 0.5, "diameter": 24.25, "thickness": 2.38, "weight": 7.8}, {"_id": "65c8c78845d911984d98f6c4", "currency": "EUR", "reverse_id": "SVN200701100REG", "obverse_id": ["EUR200702100FRO"], "country": "SVN", "commemorative": False, "series": 1, "min_year": 2007, "denomination": 1, "diameter": 23.25, "thickness": 2.33, "weight": 7.5}, {"_id": "65c8c78845d911984d98f6c5", "currency": "EUR", "reverse_id": "SVN200701200REG", "obverse_id": ["EUR200702200FRO"], "country": "SVN", "commemorative": False, "series": 1, "min_year": 2007, "denomination": 2, "diameter": 25.75, "thickness": 2.2, "weight": 8.5}]}], "country": "SVN"} print(count_objects_with_key(data1, "commemorative")) # 输出:8
测试第二组数据
data2 = {"series": 2, "coins": [{"_id": "65c8c78845d911984d98f724", "currency": "EUR", "reverse_id": "VAT200502001REG", "obverse_id": ["EUR199901001FRO"], "country": "VAT", "commemorative": False, "series": 2, "min_year": 2005, "max_year": 2005, "denomination": 0.01, "diameter": 16.25, "thickness": 1.67, "weight": 2.3}, {"_id": "65c8c78845d911984d98f725", "currency": "EUR", "reverse_id": "VAT200502002REG", "obverse_id": ["EUR199901002FRO"], "country": "VAT", "commemorative": False, "series": 2, "min_year": 2005, "max_year": 2005, "denomination": 0.02, "diameter": 18.75, "thickness": 1.67, "weight": 3.06}, {"_id": "65c8c78845d911984d98f726", "currency": "EUR", "reverse_id": "VAT200502005REG", "obverse_id": ["EUR199901005FRO"], "country": "VAT", "commemorative": False, "series": 2, "min_year": 2005, "max_year": 2005, "denomination": 0.05, "diameter": 21.25, "thickness": 1.67, "weight": 3.92}, {"_id": "65c8c78845d911984d98f727", "currency": "EUR", "reverse_id": "VAT200502010REG", "obverse_id": ["EUR199901010FRO"], "country": "VAT", "commemorative": False, "series": 2, "min_year": 2005, "max_year": 2005, "denomination": 0.1, "diameter": 19.75, "thickness": 1.93, "weight": 4.1}, {"_id": "65c8c78845d911984d98f728", "currency": "EUR", "reverse_id": "VAT200502020REG", "obverse_id": ["EUR199901020FRO"], "country": "VAT", "commemorative": False, "series": 2, "min_year": 2005, "max_year": 2005, "denomination": 0.2, "diameter": 22.25, "thickness": 2.14, "weight": 5.74}, {"_id": "65c8c78845d911984d98f729", "currency": "EUR", "reverse_id": "VAT200502050REG", "obverse_id": ["EUR199901050FRO"], "country": "VAT", "commemorative": False, "series": 2, "min_year": 2005, "max_year": 2005, "denomination": 0.5, "diameter": 24.25, "thickness": 2.38, "weight": 7.8}, {"_id": "65c8c78845d911984d98f72a", "currency": "EUR", "reverse_id": "VAT200502100REG", "obverse_id": ["EUR199901100FRO"], "country": "VAT", "commemorative": False, "series": 2, "min_year": 2005, "max_year": 2005, "denomination": 1, "diameter": 23.25, "thickness": 2.33, "weight": 7.5}, {"_id": "65c8c78845d911984d98f72b", "currency": "EUR", "reverse_id": "VAT200502200REG", "obverse_id": ["EUR199901200FRO"], "country": "VAT", "commemorative": False, "series": 2, "min_year": 2005, "max_year": 2005, "denomination": 2, "diameter": 25.75, "thickness": 2.2, "weight": 8.5}]} print(count_objects_with_key(data2, "commemorative")) # 输出:8
注意事项
- 该函数会遍历所有嵌套层级,无论数据结构多复杂都能覆盖
- 如果数据存在循环引用(如字典引用自身),会导致递归无限循环,这种场景需要额外添加循环检测逻辑
- 兼容常见JSON数据类型:对象(dict)、数组(list/tuple)、字符串、数字、布尔值、null(None)
内容的提问来源于stack exchange,提问作者Klak031
相关产品推荐
相关产品推荐

