Python for/if语句遍历列表时跳过元素的问题如何修复
问题根源
遍历列表的同时直接对原列表执行remove()删除操作,会触发列表索引实时偏移,遍历指针按原有顺序向后移动时,会直接漏掉被删除元素后移上来的项。
对应你的代码执行流程是这样的:
- 初始
list1索引0到7依次对应值[47,48,49,50,51,52,53,54],遍历到索引3时拿到值50,满足>=50的判断条件,执行删除后列表立刻变成[47,48,49,51,52,53,54],原本在索引4位置的51直接前移到了索引3 - 下一轮遍历指针直接走到索引4,拿到的是移位后落在索引4的52,前移到索引3的51就被完全跳过了。后续删除52时同理,又会跳过前移的53,最终就出现一半符合条件的元素漏判的结果。
修复方案
以下是三种可直接运行的正确写法,按需选择即可:
方案1:遍历列表副本修改原列表
遍历的时候不直接操作正在修改的原列表,而是遍历原列表的切片副本,遍历数据源不受原列表修改的影响:
list1 = [47, 48, 49, 50, 51, 52, 53, 54] list2 = [] # 遍历list1的切片副本,和原列表内容一致但完全独立 for num in list1[:]: if num >= 50: list1.remove(num) list2.append(num) print(list1) # 输出 [47, 48, 49] print(list2) # 输出 [50, 51, 52, 53, 54]
方案2:列表推导式直接拆分列表(最推荐)
不需要在循环里反复执行删除操作,逻辑清晰且执行效率最高,是Python场景下的常规写法:
list1 = [47, 48, 49, 50, 51, 52, 53, 54] list2 = [num for num in list1 if num >= 50] list1 = [num for num in list1 if num < 50] print(list1) # 输出 [47, 48, 49] print(list2) # 输出 [50, 51, 52, 53, 54]
方案3:倒序遍历原列表
如果一定要在遍历原列表时做删除操作,就从列表末尾往开头遍历,删除元素只会影响已经遍历过的索引位置,不会干扰未遍历的元素:
list1 = [47, 48, 49, 50, 51, 52, 53, 54] list2 = [] # 从最后一个索引倒序遍历到索引0 for i in range(len(list1)-1, -1, -1): num = list1[i] if num >= 50: list1.pop(i) list2.append(num) # 倒序取出的元素是逆序的,反转后和预期顺序一致 list2.reverse() print(list1) # 输出 [47, 48, 49] print(list2) # 输出 [50, 51, 52, 53, 54]
日常开发优先选择方案2,不存在遍历中修改列表的副作用,代码可读性和执行效率都远高于循环内删除的写法。
内容的提问来源于stack exchange,提问作者frenchfries
相关产品推荐
相关产品推荐

