Python for循环中调用list.append为何触发无限循环
Python for循环与list.append异常问题解答
注:以下示例会将代码中的变量名list替换为my_list——list是Python内置的列表类型关键字,直接作为变量名使用会覆盖内置功能,属于不规范编码习惯。
核心执行逻辑
三个问题的根源完全一致,先明确Python遍历列表的底层规则:
Python用for i in 列表遍历列表时,不会在循环启动时拷贝一份初始列表的固定快照,也不会提前记住初始列表长度,整个遍历过程直接操作原列表,执行逻辑非常简单:
- 循环启动时生成一个指向原列表的迭代器,内部只维护一个「当前遍历位置」的指针,初始指向下标0
- 每轮循环开始先做判断:如果当前指针位置 >= 列表当前的实际长度,就结束循环;否则取出指针对应位置的元素赋值给
i,指针后移一位,执行循环体内的代码 - 循环过程中只要原列表长度增加,迭代器的结束判断就会以新长度为准,完全不受初始长度影响。
问题1:追加固定值1为什么会无限循环?
对应代码:
my_list = [1,2,3] for i in my_list: my_list.append(1)
执行过程逐轮拆解:
- 初始列表长度为3,指针从下标0启动
- 第1轮:取下标0的元素1,指针移到1,追加1,列表变成长度4的
[1,2,3,1] - 第2轮:取下标1的元素2,指针移到2,追加1,列表长度变为5
- 第3轮:取下标2的元素3,指针移到3,追加1,列表长度变为6
- 第4轮:取下标3的元素(就是上一轮刚追加的1),指针移到4,追加1,列表长度变为7
- 后续每一轮都能取到新追加的1,指针永远追不上不断增长的列表长度,循环永远不会触发结束条件,自然进入无限循环。
问题2:追加当前遍历值i为什么会无限循环,还重复生成[1,2,3]序列?
对应代码:
my_list = [1,2,3] for i in my_list: my_list.append(i)
核心触发逻辑和第一个问题完全一致,只是追加的内容从固定值1变成了当前遍历到的元素,执行过程如下:
- 初始列表为
[1,2,3],长度3,指针从0启动 - 前三轮依次取下标0的1、下标1的2、下标2的3,分别追加到列表末尾,此时列表变成长度6的
[1,2,3,1,2,3],指针移到下标3 - 第4轮取下标3的元素(就是第一轮追加的1),把1追加到末尾,指针移到4
- 第5轮取下标4的元素(第二轮追加的2),把2追加到末尾,指针移到5
- 第6轮取下标5的元素(第三轮追加的3),把3追加到末尾,指针移到6
- 后续就会不断重复取1、2、3再追加的流程,列表会无限拼接
[1,2,3]的重复序列,长度持续增长,永远不会停止。
问题3:为什么加了print的代码运行时终端没有任何输出?
对应代码:
my_list = [1,2,3] for i in my_list: my_list.append(1) print(my_list)
原因非常直白:
Python是逐行顺序执行的,print(my_list)写在for循环的外部,必须等for循环完全执行完毕才会被运行。但前面的for循环是无限循环,会一直占用计算资源往列表里追加元素,永远不会执行结束,自然永远轮不到print语句执行,终端看不到任何输出。如果运行时间足够长,列表占用的内存会持续上涨,最终可能触发内存溢出导致程序崩溃,还是等不到print语句运行。
如果需要实现「遍历初始列表的元素、追加固定次数内容」的需求,只要遍历初始列表的副本即可,副本长度固定,不会受原列表变动影响,参考写法:
my_list = [1,2,3] # 遍历初始列表的浅拷贝,拷贝内容固定为初始的3个元素 for i in my_list.copy(): my_list.append(1) print(my_list) # 正常输出 [1,2,3,1,1,1]
内容的提问来源于stack exchange,提问作者Andrei M.
相关产品推荐
相关产品推荐

