摘要:my_list = [1, 2, 3, 4, 5]for i in range(len(my_list)): if my_list[i] % 2 == 0: my_list.pop(i) # 删除偶数元素
一个让代码崩溃的经典错误,先看这段代码,你能看出问题吗?
my_list = [1, 2, 3, 4, 5]for i in range(len(my_list)): if my_list[i] % 2 == 0: my_list.pop(i) # 删除偶数元素运行后直接报错:IndexError: list index out of range!
原因揭秘:
当用range(len)生成固定索引范围(比如0-4)后,若在遍历时删除元素(如删除索引1的元素),列表长度会动态缩短,但索引i仍会递增到原最大索引值,导致访问不存在的元素。
方案1:倒序删除法(推荐指数⭐⭐⭐⭐⭐)
从后往前遍历,元素位置变化不影响未处理的索引:
原理:删除元素时,前面的索引不会变动。
方案2:while循环控制法(推荐指数⭐⭐⭐⭐)
手动管理索引,删除时不递增:
方案3:副本遍历法(推荐指数⭐⭐⭐)
遍历原列表的副本,操作原列表:
注意:适合小规模数据,大列表会有内存开销。
方案4:列表推导式(推荐指数⭐⭐⭐⭐⭐)
一行代码生成新列表,简洁高效:
1、嵌套列表遍历
使用递归处理多层结构:
2、 字典遍历雷区
直接遍历字典时修改会触发RuntimeError:
3、大数据量优化
用生成器避免内存爆满:
结论:列表推导式速度最快,倒序删除法内存最优。
简单场景:优先用列表推导式或倒序遍历复杂逻辑:用while循环精准控制索引超大数据:生成器+分块处理工具推荐:NumPy:数值计算提速神器Pandas:表格数据一键过滤来源:信息科技云课堂