Python对列表中元素进行删除时,出现了一个非常奇怪的事情,求各位大佬解惑。

 lst=[1,2,2,12.8,'a','a','列表',2,'python',(2,'c'),{'name':'tom','age':18},'',True,[1,'a',3],{1,3,'a'}]

for i in lst:
    if i == 2:
        lst.remove(i)


使用for循环删除lst中的2,但是运行结果是:


[1, 12.8, 'a', 'a', '列表', 2, 'python', (2, 'c'), {'name': 'tom', 'age': 18}, '', True, [1, 'a', 3], {1, 'a', 3}]

为什么 元素 '列表' 后边的2,没有被删除?求各位大神解惑。

remove只删除第一个匹配的元素啊!删了一个结束了,不会删后面的。而且你这个循环遍历是没有意义的。就相当于执行了remove(2)

考虑下面的代码:

k = 0
for i in range(0, len(lst)-1-k):
    if (lst[i] == 2):
            del lst[i]
                k++

在遍历中删除时比较危险的,列表长度会随着改变,如果不加记录删除个数的k,就会indexOutOfBound
当然这样写很土。。。如果有人有更简便的方法就更好了

因为remove改变了迭代器状态,它实际上会掉过删除元素之后的那个

这么写

    lst=[1,2,2,12.8,'a','a','列表',2,'python',(2,'c'),{'name':'tom','age':18},'',True,[1,'a',3],{1,3,'a'}]
    for i in list(lst):
        if i == 2:
            lst.remove(i)
    print(lst)

一般我是这么处理的。
lst=[1,2,2,12.8,'a','a','列表',2,'python',(2,'c'),{'name':'tom','age':18},'',True,[1,'a',3],{1,3,'a'}]
lst2=[x for x in lst if x!=2]
print (lst2)

代码如下:

lst = [1, 2, 2, 12.8, 'a', 'a', '列表', 2, 'python', (2, 'c'), {'name': 'tom', 'age': 18}, '', True, [1, 'a', 3],
           {1, 3, 'a'}]
i = 0
while i < len(lst):
        if lst[i] == 2:
                lst.pop(i)
                i -= 1
        i += 1
print(lst)

你和这位博主遇到一样的问题,具体原因你可以看下
https://www.cnblogs.com/bananaplan/p/remove-listitem-while-iterating.html

remove改变了原list的迭代次序(跳过了第二个2),而remove是按原有迭代器的地址去删除(保留了第三个2误删了python)

这个问题在考remove和遍历的知识点时经常遇到,原因上面楼里已讲过,慎用。上面一位楼主写的代码最简洁也最安全:
lst2=[x for x in lst if x!=2]
也可以下面这样,对楼主的代码改动最小:

lst=[1,2,2,12.8,'a','a','列表',2,'python',(2,'c'),{'name':'tom','age':18},'',True,[1,'a',3],{1,3,'a'}]
for i in lst[:]: #注意此处有改动
    if i == 2:
        lst.remove(i)
print(lst)