Python嵌套列表扁平化递归函数触发RecursionError问题求解
问题原因分析
- 类型判断逻辑完全颠倒
你写的判断条件if isinstance(item, Iterable) or isinstance(item, (str,bytes))存在两个致命问题:str和bytes本身就属于Iterable类型,这个or的逻辑完全多余,且完全违背需求- 需求是「只有非字符串/字节的可迭代对象才需要递归展开」,你写成了「只要是可迭代对象、或者字符串/字节就递归」,导致碰到单个字符串(比如示例里的
'd')时,会无限递归:遍历'd'得到的元素还是长度为1的字符串,永远满足递归条件,最终触发递归深度超限错误
- 函数无返回值,调用逻辑错误
你的flattenme函数没有任何返回值,默认返回None,你调用list(flattenme(array))相当于把None转为列表,就算递归逻辑修复,这一步也会直接抛出类型错误。你当前的写法是把结果存在全局变量flattened里,调用完函数直接打印这个全局变量即可,不需要再加list()转换。 - 缺少必要的导入声明
Iterable不属于Python内置顶层类型,你需要先执行from collections.abc import Iterable导入,否则类型判断步骤会直接抛出名称错误。
修复后的代码示例
版本1:保留全局变量的写法(适配你原有逻辑)
from collections.abc import Iterable array = [[1,2,3,['a','b','c'],4],'d', [5,6],[7],8,9] flattened = [] def flattenme(iteritem): for item in iteritem: # 修正判断:是可迭代对象 且 不是字符串/字节时才递归 if isinstance(item, Iterable) and not isinstance(item, (str, bytes)): flattenme(item) else: flattened.append(item) flattenme(array) print(f"flatten method: {flattened}")
版本2:生成器写法(更优雅,不需要全局变量)
from collections.abc import Iterable array = [[1,2,3,['a','b','c'],4],'d', [5,6],[7],8,9] def flattenme(iteritem): for item in iteritem: if isinstance(item, Iterable) and not isinstance(item, (str, bytes)): yield from flattenme(item) else: yield item print(f"flatten method: {list(flattenme(array))}")
递归认知误区说明
- 你没有明确递归的终止边界:递归的核心是每一层调用都要向终止条件靠近,你错误地把本该属于终止节点的字符串类型划进了递归分支,导致递归永远不会停止
- 你混淆了递归结果的传递方式:递归结果要么通过外部容器存储、要么通过返回值逐层传递,你同时用了两种逻辑,既往全局列表加元素,又尝试从函数返回值拿结果,逻辑完全冲突。
内容的提问来源于stack exchange,提问作者Dan
相关产品推荐
相关产品推荐

