使用remove方法遍历Python列表时异常现象的原因解析
嘿,这个问题其实是遍历列表时修改列表最常见的坑之一,我来给你掰扯清楚~
问题原因分析
你遇到的核心问题在于遍历列表的同时直接修改了这个列表本身,还有个容易忽略的小细节:temp_list = ms_list并没有创建新列表,只是给原列表起了个别名——也就是说你遍历的temp_list和修改的ms_list其实是同一个对象。
当Python按索引顺序遍历列表时,列表长度的变化会导致索引错位:
- 初始列表:
['IJM612C0', 'IJM612C1', 'IJM612C2', 'IJM612C3', 'IJM666', 'IJM667'] - 第一次循环取索引0的元素
IJM612C0,符合条件被移除,列表变成:['IJM612C1', 'IJM612C2', 'IJM612C3', 'IJM666', 'IJM667'] - 第二次循环会取索引1的元素(原索引1的
IJM612C1现在在索引0,但循环已经走到下一个索引了),取到的是IJM612C2,移除后列表变成:['IJM612C1', 'IJM612C3', 'IJM666', 'IJM667'] - 后续循环继续按索引推进,直接跳过了没被遍历到的
IJM612C1和IJM612C3,最终就出现了和预期不符的结果
正确的解决方式
你已经用列表推导式找到了解决方案,这确实是Python里处理这类问题最简洁高效的方式,比如:
def filter_ms_list(ms_list): trash_suffix = ['C0', 'C1', 'C2', 'C3', 'C4'] return [ms for ms in ms_list if not any(ms.endswith(suffix) for suffix in trash_suffix)]
如果一定要用遍历+移除的写法,有两种可靠的思路:
- 遍历原列表的副本:这样修改原列表不会干扰遍历的顺序
def filter_ms_list(ms_list): trash_suffix = ['C0', 'C1', 'C2', 'C3', 'C4'] # 用list()或ms_list[:]创建原列表的副本 for ms in list(ms_list): for suffix in trash_suffix: if ms.endswith(suffix): ms_list.remove(ms) break return ms_list
- 倒序遍历列表:倒序遍历的时候,移除前面的元素不会影响已经遍历过的后面元素的索引
def filter_ms_list(ms_list): trash_suffix = ['C0', 'C1', 'C2', 'C3', 'C4'] # 从最后一个元素往回遍历 for ms in reversed(ms_list): for suffix in trash_suffix: if ms.endswith(suffix): ms_list.remove(ms) break return ms_list
内容的提问来源于stack exchange,提问作者MrMag
相关产品推荐
相关产品推荐

