为何Python函数中的for循环仅迭代一次,仅移除一个奇数?
问题:遍历列表移除奇数时漏删元素的原因?
我写了一个Python函数onlyEvens,想移除列表里所有奇数:
def onlyEvens(L): # TODO - your code goes here for i in L: if i%2 != 0: L.remove(i) return L if __name__ == '__main__': result = onlyEvens([3,5,6,2,10,8]) print(result)
实际运行后只移除了奇数3,没删掉5,最终输出[6, 2, 10, 8],这是为什么?
问题原因
核心问题是在遍历列表的同时直接修改列表(移除元素)会打乱迭代器的遍历顺序,具体过程如下:
- 初始列表是
[3,5,6,2,10,8],Python的for循环基于列表的迭代器遍历,一开始迭代器指向索引0的元素3。 - 检测到3是奇数,调用
L.remove(i)把它删掉,此时列表变成[5,6,2,10,8]——原来索引1的元素5现在移到了索引0的位置。 - 循环迭代器会自动推进到下一个索引(也就是1),此时索引1对应的元素是6,直接跳过了现在在索引0的5,导致这个奇数没被检查和移除。
修复方案
方案1:遍历列表的副本
通过切片L[:]创建原列表的副本,遍历副本的同时修改原列表,就不会影响遍历顺序:
def onlyEvens(L): for i in L[:]: if i % 2 != 0: L.remove(i) return L
方案2:使用列表推导式(更推荐)
列表推导式是Python中处理这类筛选场景更简洁高效的写法,直接生成只包含偶数的新列表:
def onlyEvens(L): return [x for x in L if x % 2 == 0]
内容的提问来源于stack exchange,提问作者Ronaldo Gomez Santos
相关产品推荐
相关产品推荐

