我想编写一个函数,从列表中删除偶数(例如 xs=[1,2,3,4,5,6]),然后返回剩余的列表。需要帮助。谢谢注意:我不能使用任何内置函数,如删除排序等,但只能使用删除语句。
3 回答
由于您需要返回剩余列表,因此您不应该删除而是过滤:
[v for v in xs if v % 2 == 1]
这将创建一个包含所有奇数的列表:
>>> xs = [1, 2, 3, 4, 5, 6]
>>> [v for v in xs if v % 2 == 1]
[1, 3, 5]
明显的方法不起作用:
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 的内容;既然迭代器协议是公开的,他们真的不需要谈论将内部计数器保存在某个未指定的地方......</p>
xs=[1,2,3,4,5,6]
not_even = []
for i in xs:
if i%2 != 0:
not_even.append(i)
print not_even
#output: [1, 3, 5]
您也可以使用列表推导来做到这一点:
[i for i in xs if i%2 != 0]