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

迭代时修改可变可迭代对象是否合规?以BFS队列操作为例

为什么BFS中迭代时修改队列是可接受的?

问题背景

大家都知道通常不建议在迭代可变可迭代对象时修改它,但在学习BFS(广度优先搜索)实现二叉树层级遍历这类场景时,典型写法会在while循环里,基于队列的初始长度遍历当前层级元素,同时弹出队首元素并将子节点添加到队列中。这种场景下修改可变可迭代对象(队列)是否正常且可接受?

代码示例

def levelOrder(self, root: Optional[TreeNode]) -> List[List[int]]:
    res = []
    q = collections.deque()     # 要实现按层遍历,所以用广度优先搜索

    if root:                    # 根节点不为空时加入队列
        q.append(root)

    while q:                    # 队列非空时持续循环
        val = []                # 初始化存储当前层节点值的列表
        print(f'len(q) = {len(q)}\n')
        for i in range(len(q)):     # 基于队列初始长度遍历当前层所有节点
            print(f'i = {i}, len(q) = {len(q)}, q = {list(q)}\n')
            node = q.popleft()      # BFS取出队首元素,记录其值
            val.append(node.val)
            if node.left:           # 左子节点存在则加入队列(待下一层处理)
                q.append(node.left)
            if node.right:          # 右子节点存在则加入队列(待下一层处理)
                q.append(node.right)

        res.append(val)             # 当前层所有节点处理完毕,将结果加入总列表
    return res                      # 队列为空时返回最终结果

解答

这种修改是完全正常且可接受的,核心原因在于BFS的层级遍历逻辑特意利用了队列的可变特性,且循环边界是固定的:

  • 内层for循环的range(len(q))是在循环开始前就计算出当前队列的长度(也就是当前层的节点总数),range()生成的是固定的整数序列,后续队列添加子节点的操作不会改变这个循环的迭代次数
  • 我们修改队列的目的是把下一层的节点加入队列,供下一轮while循环处理,这正是BFS层级遍历的核心逻辑:处理完当前层后,自然衔接下一层的待处理节点

这和“在迭代列表时删除/插入元素导致遍历异常”的情况完全不同——后者是因为迭代器依赖列表的实时长度,而这里的循环次数预先固定,队列的修改是在当前层遍历的逻辑之外,用于构建下一层的任务,不会干扰当前层的遍历流程。

简单说,这不是“在迭代时破坏迭代对象”,而是利用可变队列的特性实现层级间的衔接,属于BFS层级遍历的标准、正确写法。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.08 18:05:03