Python递归获取嵌套字典所有值的代码修正与原理说明
问题复现
原有实现代码如下,预期提取嵌套字典中的所有非字典类型值,实际运行仅输出[1, 2],无法获取嵌套字典内部的值:
def get_values(d): values = [] for v in d.values(): if isinstance(v, dict): get_values(v) else: values.append(v) return values a = {4: 1, 6: 2, 7: {8: 3, 9: 4, 5: {10: 5}, 2: 6, 6: {2: 7, 1: 8}}} print(get_values(a))
错误原因分析
核心问题是递归调用的返回值没有被接收和合并:
每次进入get_values函数时,都会初始化一个全新的空列表values作为当前函数的局部变量。当遍历到嵌套字典触发递归调用时,内层函数确实会遍历内层字典的内容、把值存在内层自己的values里,但内层函数返回这个列表后,外层代码没有做任何接收和合并操作,内层收集到的所有值会被直接丢弃。最终外层函数只会返回当前最外层字典里的非字典值,也就是[1,2]。
修正后的可运行代码
仅需修改递归调用处的逻辑,接收返回值并合并到当前层结果列表即可,修改后代码如下,运行可得到预期输出[1, 2, 3, 4, 5, 6, 7, 8]:
def get_values(d): values = [] for v in d.values(): if isinstance(v, dict): # 接收递归返回的内层结果,合并到当前层列表 values.extend(get_values(v)) else: values.append(v) return values a = {4: 1, 6: 2, 7: {8: 3, 9: 4, 5: {10: 5}, 2: 6, 6: {2: 7, 1: 8}}} print(get_values(a))
修改思路与递归实现逻辑
递归遍历嵌套结构只需要抓住两个核心要点,原代码已经写对了其中一个,只差结果传递的环节:
- 明确终止条件:当遍历到的值不是字典类型时,不需要继续向下递归,直接把值收入结果集即可,这部分原代码逻辑正确。
- 递归结果向上合并:当遍历到的值是字典类型时,调用自身处理这个子字典,并且要把递归返回的子字典所有值,合并到当前层的结果列表里,不能丢弃返回值。
以示例字典为例,完整执行流程如下:
- 第一层(最外层字典a)遍历得到三个值:1、2、子字典
{8: 3, 9: 4, 5: {10: 5}, 2: 6, 6: {2: 7, 1: 8}},1、2为普通值直接加入第一层结果列表 - 遇到子字典触发第二层递归,第二层遍历得到值3、4、子字典
{10:5}、6、子字典{2:7,1:8},3、4、6为普通值加入第二层结果 - 第二层遍历到两个子字典,分别触发第三层递归:处理
{10:5}时拿到普通值5,无更深嵌套,返回[5]合并到第二层结果;处理{2:7,1:8}时拿到普通值7、8,返回[7,8]合并到第二层结果 - 第二层最终收集到
[3,4,5,6,7,8]返回给第一层,第一层将该列表与已有的[1,2]合并,得到最终正确结果。
内容的提问来源于stack exchange,提问作者Jack
相关产品推荐
相关产品推荐

