You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

带索引路径的任意深度嵌套列表扁平化迭代实现问询

迭代式实现深度优先扁平化迭代器(带索引路径)

嘿,这个问题我之前也琢磨过!递归生成器虽然写起来快,但碰到极深的嵌套时容易触发RecursionError,而且有时候就是想搞个纯迭代的实现。其实用Python标准库(甚至不用额外导入itertools都能行)完全能搞定,核心思路就是用**栈(stack)**模拟递归过程,全程不用递归,还能灵活适配各种嵌套场景~

核心实现思路

深度优先遍历的本质是「先处理子节点,再处理兄弟节点」,我们可以用栈来保存待处理的迭代上下文:每个栈元素包含「当前要遍历的可迭代对象的迭代器」和「当前节点的父索引路径」。每次从栈顶取出元素处理,遇到子列表时,先把当前迭代器的剩余部分放回栈(等子列表处理完再回来处理),再把子列表的迭代器和新路径压入栈,以此实现深度优先的顺序。

代码实现

这里我们还做了一个常见的优化:跳过字符串/字节串的拆分(因为它们虽然是可迭代对象,但通常我们不想把"abc"拆成['a','b','c']),如果需要拆分字符串,去掉对应判断即可。

from collections.abc import Iterable

def flatten_with_path(nested_collection):
    # 栈元素格式:(当前可迭代对象的迭代器, 父节点的索引路径)
    stack = [(iter(nested_collection), [])]
    
    while stack:
        current_iter, parent_path = stack.pop()
        for idx, item in enumerate(current_iter):
            # 判断是否是需要继续展开的嵌套可迭代对象
            if isinstance(item, Iterable) and not isinstance(item, (str, bytes)):
                # 把当前迭代器的剩余部分放回栈(后续处理兄弟节点)
                stack.append((current_iter, parent_path))
                # 把子可迭代对象和新路径压入栈(优先处理子节点)
                stack.append((iter(item), parent_path + [idx]))
                break  # 跳出循环,立即处理刚压入的子节点
            else:
                # 叶子节点,生成(元素, 索引路径)对
                yield (item, parent_path + [idx])

测试用例

我们用一个典型的嵌套列表测试:

nested_example = [1, [2, 3, [4, 5]], 6, ["hello", [7, 8]]]
for elem, path in flatten_with_path(nested_example):
    print(f"元素: {elem}, 索引路径: {path}")

输出结果(完全符合深度优先顺序):

元素: 1, 索引路径: [0]
元素: 2, 索引路径: [1, 0]
元素: 3, 索引路径: [1, 1]
元素: 4, 索引路径: [1, 2, 0]
元素: 5, 索引路径: [1, 2, 1]
元素: 6, 索引路径: [2]
元素: hello, 索引路径: [3, 0]
元素: 7, 索引路径: [3, 1, 0]
元素: 8, 索引路径: [3, 1, 1]

为什么这个实现更优?

  • 无递归深度限制:不管嵌套多深,都不会触发RecursionError,适合处理极端场景;
  • 内存效率高:用迭代器而非完整列表存储待处理内容,不会一次性加载所有元素到内存;
  • 通用性强:支持所有实现了Iterable接口的对象(不止列表),比如元组、集合等,只要调整判断逻辑就能适配更多场景;
  • 纯标准库:只用到了内置的Iterable抽象和栈结构,不需要额外依赖。

如果一定要结合itertools的话,其实可以用itertools.chain来合并迭代器,但上面的实现已经足够简洁高效,没必要画蛇添足啦~

内容的提问来源于stack exchange,提问作者RBF06

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.05.19 10:17:49