如何在Python中遍历嵌套字典/列表并提取指定键值对?
遍历嵌套字典/列表提取指定键值对条目
需求说明
遍历任意深度和长度的嵌套字典或列表,返回所有匹配指定键值对的条目:
- 示例1:从给定数据中提取所有
{'dd': 22} - 示例2:从HTML结构的嵌套数据中提取所有
{'@content': 'cccc'}
原始尝试代码
d = {'a': 'foo', 'b': [{'cc': 11}, {'dd': 22}], 'c': [{'dd': 22}, {'ff': 33}]} def navigate_html(d, key='', value='', ll=[]): if isinstance(d, list): for v in d: yield from navigate_html(v, key, value, ll) if isinstance(d, dict): for k, v in d.items(): if k == key and v == value: ll.append({k: v}) else: yield from navigate_html(v, key, value, ll) return ll for i in navigate_html(d, 'dd', 22): print('---', i)
原始代码存在的问题
- 默认可变参数陷阱:
ll=[]是可变对象,多次调用函数时会复用同一个列表,导致结果累积旧数据,出现不符合预期的输出。 - 逻辑冲突:混用了生成器(
yield from)和列表返回(return ll),调用方式和返回值逻辑不统一,容易造成混乱。
改进方案
方案1:使用生成器返回结果
通过生成器逐个yield匹配的条目,最后转成列表即可得到结果:
def find_key_value_pairs(data, target_key, target_value): if isinstance(data, list): for item in data: yield from find_key_value_pairs(item, target_key, target_value) elif isinstance(data, dict): for key, value in data.items(): if key == target_key and value == target_value: yield {key: value} yield from find_key_value_pairs(value, target_key, target_value)
测试示例1
d = {'a': 'foo', 'b': [{'cc': 11}, {'dd': 22}], 'c': [{'dd': 22}, {'ff': 33}]} result = list(find_key_value_pairs(d, 'dd', 22)) print(result) # 输出:[{'dd': 22}, {'dd': 22}]
测试示例2
d1={'doctype': ['html'], 'html': [{'@lang': 'en-EN', '#text': "ttt", 'head': [{'#text': 'abc', 'meta': [{'@charset': 'utf-8', '#text': ''}, {'@name': 'viewport', '@content': 'width=device-width, initial-scale=1.0, maximum-scale=1.0, user-scalable=no', '#text': ''}, {'@name': 'description', '@content': 'cccc', '#text': '', 'meta': [{'@name': 'keywords', '@content': 'cccc', '#text': ''}] }] }] }] } result = list(find_key_value_pairs(d1, '@content', 'cccc')) print(result) # 输出:[{'@content': 'cccc'}, {'@content': 'cccc'}]
方案2:直接返回结果列表
如果更习惯直接获取列表,可通过递归收集结果并返回:
def find_key_value_pairs(data, target_key, target_value): result = [] if isinstance(data, list): for item in data: result.extend(find_key_value_pairs(item, target_key, target_value)) elif isinstance(data, dict): for key, value in data.items(): if key == target_key and value == target_value: result.append({key: value}) result.extend(find_key_value_pairs(value, target_key, target_value)) return result
调用方式和输出与方案1一致,无需额外转成列表。
内容的提问来源于stack exchange,提问作者Alessandro Bitetto
相关产品推荐
相关产品推荐

