Python 循环列表删除元素的注意事项

Table of Contents

示例一

运行以下 Python 代码,结果是什么?

data = [1, 2, 3, 4, 5]
for i in data:
    data.remove(i)
print(data)

如果你的答案是 [2, 4],那就不用往下看了。

结果说明

  • 当循环第一次删除元素 1 后,后面的元素后往前移动,这时 data = [2, 3, 4, 5]

  • 此时,指针会指向新 data 中第二个元素,即 3,执行 remove,后面的元素后往前移动,这时 data = [2, 4, 5]

  • 这时,指针会指向新 data 中第三个元素,即 5,执行 remove,这时 data = [2, 4],且 5 为新 data 中最后一个元素,遍历结束

示例二

比如,按照一定要求将列表中元素筛选出来。

data = list(range(10))  # [0, 1, 2, 3, 4, 5, 6, 7, 8, 9]
for i in data:
    if i > 5:
        pass
    else:
        data.remove(i)

上面的代码乍一看,将 [0, 1, 2, 3, 4, 5, 6, 7, 8, 9] 列表中大于 5 的元素筛出来,但实际结果是 data = [1, 3, 5, 6, 7, 8, 9],原因和上面是一样的。

总结

那更好的做法是什么?

  • 列表解析
data = [0, 1, 2, 3, 4, 5, 6, 7, 8, 9]
data = [i for i in data if i > 5]
  • filter 函数
data = [0, 1, 2, 3, 4, 5, 6, 7, 8, 9]
data = list(filter(lambda i: i > 5, data))  # 注意,Python3 中 filter 函数返回的是可迭代对象,所以外面加了 `list`