明显的方法不起作用:
for index, value in enumerate(xs):
if not value % 2:
del xs[index]
或者,更糟糕的是,它恰好在这种特殊情况下有效,但这只是因为你非常幸运(你的老师甚至可能指望你落入这个陷阱)。
为什么?好吧,当你del i[0] 时,这会降低其他所有内容。所以当你下次检查i[1]时,那不是原来的i[1],而是原来的i[2]。你永远不会检查,因此永远不能删除原始的i[1]!
这在 for.* 的文档中的一个灰色大注释中进行了解释。*
正如 Martijn Pieters 所说,最好的解决方案是一开始就不要删除。
如果您不关心改变原始列表(如果没有其他对象引用相同的列表,并且您的老师不喜欢技巧问题,您不必关心),只需创建并返回一个新列表,如他的回答。即使您确实需要改变原始列表,xs[:] = [v for v in xs if v % 2 == 1] 也会这样做,就像就地删除一样。
但如果您出于某种原因必须就地删除(听起来可能是您的任务的要求),最简单的方法是从头开始向后工作:
for index, value in list(enumerate(xs))[::-1]:
if not value % 2:
del xs[index]
由于从列表中删除一个值只会将其后的值向下移动,因此以相反的顺序遍历列表意味着我们永远不会迷路并跳过我们想要测试的元素。
* 这个解释读起来像 Python 1.x 的东西;既然迭代器协议是公开的,他们真的不需要谈论将内部计数器保存在某个未指定的地方......