在 Python 中从列表中删除项

2023-09-20 09:31:52

要从list中删除项目 ,我们有两个选择。一种是使用 del mylist[i]其中 i 是索引。另一个是调用mylist.remove(i)方法,其中i是列表中的项。

通常,如果满足某个条件,您将从列表中删除项目。假设我们要从mylist中删除偶数,带有索引的迭代导致错误

mylist=[5,3,7,8,20,15,2,6,10,1]
l=len(mylist)
for i in range(l):
    if (mylist[i]%2==0):
        del mylist[i]

输出:

IndexError: list index out of range

这是因为列表对象会随着项目被删除而动态调整大小。因此,这种在迭代列表时删除项目的方法不起作用。解决此问题的方法是使用递减循环。在此示例中,列表大小为 10,因此索引从 9 递减为 0

mylist=[5,3,7,8,20,15,2,6,10,1]
for i in range(len(mylist)-1, -1, -1):
    if mylist[i]%2==0:
        del mylist[i]
print (mylist)

输出:

[5, 3, 7, 15, 1]

调用 List 对象remove()方法也会给出不正确的结果

mylist=[5,3,7,8,20,15,2,6,10,1]
for i in mylist:
    if (i%2==0):
        mylist.remove(i)
print (mylist)

输出:

[5, 3, 7, 20, 15, 6, 1]

我们可以看到偶数 20 和 6 没有被删除。这是因为当 i 变为 8 时,它被删除,右侧的项目向左移动一个位置,20 在下一次迭代之前成为当前项目。同样,在删除 2 后,6 将成为当前项目并转义删除条件。

这种奇怪情况的答案是使用list comprehension

mylist=[5,3,7,8,20,15,2,6,10,1]
mylist=[i for i in mylist if i%2!=0]
print(mylist)

输出:

[5, 3, 7, 15, 1]

我们还可以使用内置的filter()函数。第一个参数是一个函数本身,它应用于列表中的每个项目,并返回一个迭代器,其中包含参数函数计算结果为 true 的列表项。

mylist=[5,3,7,8,20,15,2,6,10,1]
mylist=list(filter(lambda x:x%2!=0, mylist))
print (mylist)

输出:

[5, 3, 7, 15, 1]

另一种方法是使用itertools模块中定义的filterfalse()函数。

from itertools import filterfalse
mylist=[5,3,7,8,20,15,2,6,10,1]
def iseven(i):
    if i%2==0:
        return i
mylist=list(filterfalse(iseven, mylist))
print (mylist)

输出:

[5, 3, 7, 15, 1]