尝试删除列表中的项目,但没有成功。
>>> r = [1,2,3,4,5]
>>> for i in r:
if i<3:
del i
>>> print r
[1, 2, 3, 4, 5]
我甚至尝试过滤它,
>>> def f(i):
True if i>2 else False
>>> print list(filter(f,r))
[]
我不明白为什么第一个不起作用。当我使用filter(function,iterable)
时,我根本不理解结果。
编辑:
看到下面的Paulo的评论,现在我不明白为什么会这样。
>>> for i in r:
if i<3:
r.remove(i)
>>> print r
[3, 4, 5]
迭代器问题不应该仍然存在,并且代码不应该只删除第一个元素(r[0]
)
答案 0 :(得分:10)
改为使用列表理解:
[i for i in r if i >= 3]
并保留而不是删除。
您的过滤器永远不会返回测试;所以你总是返回None
而在布尔上下文中返回false。以下工作正常:
def f(i):
return i > 2
您的初始尝试失败,因为del i
取消绑定i
,但列表仍未受影响。仅清除本地名称i
。
如果要从列表中删除项目,则需要删除索引:
del r[0]
从列表中删除第一个元素。
即使您确实设法删除了 indices ,循环也会让人感到惊讶:
>>> for i, element in enumerate(r):
... if element < 3:
... del r[i]
...
>>> r
[2, 3, 4, 5]
此版本失败,因为for
循环使用的列表迭代器不知道您从列表中删除了元素;删除索引0处的值会向上移动列表的其余部分,但循环迭代器会查看项目1,无论如何:
r = [1, 2, 3, 4, 5]
,迭代器索引0 - &gt; element = 1
r = [2, 3, 4, 5]
,迭代器索引1 - &gt; element = 3
答案 1 :(得分:4)
我不明白为什么第一个不起作用。
它不起作用,因为语句del i
取消定义变量i
- 也就是说,它从包含它的范围(全局或本地)中删除它。
当我使用filter(function,iterable)
时,我根本不理解结果
您的函数f
不包含return语句。因此,它始终返回None
,其布尔等效值为False
。因此,filter
排除了所有值。
您应该做的是使用理解进行过滤,并替换列表,如下所示:
r = [i for i in r if i >= 3]
或者,如果您确实要删除部分原始列表并对其进行修改,请在列表的一部分上使用del
:
del r[:3]
在下面看到Paulo的评论,现在我不明白为什么[使用
remove
]有效。
因为remove(r)
在列表中搜索值r
,并删除它的第一个实例。因此,重复修改列表不会影响remove
内发生的迭代。但请注意,如果删除项目导致在列表的迭代中跳过某个项目,它仍然容易受到相同的错误。