for循环删除list元素易错笔记

如何高效删除List元素是一个值得思考的命题,如果单单考虑时间复杂度,可能会带来额外的空间复杂度。

对Pthon而言 迭代中删除List元素是一个不那么安全的行为,下面记录了一些遇到的坑(拓展性踩坑,防错):

  1. 使用del
    del是使用下标进行删除
    请看代码:

a = [0, 1, 2, 3, 4, 5, 6]
# 使用del

for i in range(len(a)):
    try:
        if a[i] == 3 or a[i] == 5:

            del a[i]
        else:
            print(i)
    except:
        print('out of : ', i)
        break

print(a)

此代码会报错:

0
1
2
out of :  5
[0, 1, 2, 5, 6]

报错的原因是删除第一个之后,下标5时会出现越界。
增加几行代码,可以看到具体原因:

a = [0, 1, 2, 3, 4, 5, 6]
# 使用del

for i in range(len(a)):
    try:
        if a[i] == 3 or a[i] == 5:
            print('i={},  a[{}] = {} ,org a={},  '.format(
                i, i, a[i], a), end='')
            del a[i]
            print('deleted a ={}'.format(a))
        else:
            print(i)
    except:
        print('out of : ', i)
        break

print(a)

输出:

0
1
2
i=3,  a[3] = 3 ,org a=[0, 1, 2, 3, 4, 5, 6],  deleted a =[0, 1, 2, 4, 5, 6]
i=4,  a[4] = 5 ,org a=[0, 1, 2, 4, 5, 6],  deleted a =[0, 1, 2, 4, 6]
out of :  5
[0, 1, 2, 4, 6]

*可以使用while来控制变量解决这个问题

  1. 使用remove:
    remove是根据值来删除

    为了简单验证,我们首先假定该list没有重复的值,并且换一种方式,挑战迭代中删除元素:

a = [0, 1, 2, 3, 4, 5, 6]
# 使用del

for i in a:
    try:
        if i == 3 or i == 6:
            print('i={},,org a={},  '.format(
                i,  a), end='')
            #del a[i]
            a.remove(i)
            print('deleted a ={}'.format(a))
        else:
            print(i)
    except:
        print('error : ', i)
        break

该代码未报错:

0
1
2
i=3,,org a=[0, 1, 2, 3, 4, 5, 6],  deleted a =[0, 1, 2, 4, 5, 6]
5
i=6,,org a=[0, 1, 2, 4, 5, 6],  deleted a =[0, 1, 2, 4, 5]
[0, 1, 2, 4, 5]

细心的朋友就会发现,这样做会造成bug,4并没有打印出来
将两个值更改以下:

a = [0, 1, 2, 3, 4, 5, 6]
# 使用del

for i in a:
    try:
        if i == 4 or i == 3:
            print('i={},,org a={},  '.format(
                i,  a), end='')
            #del a[i]
            a.remove(i)
            print('deleted a ={}'.format(a))
        else:
            print(i)
    except:
        print('error : ', i)
        break

print(a)

得到:

0
1
2
i=3,,org a=[0, 1, 2, 3, 4, 5, 6],  deleted a =[0, 1, 2, 4, 5, 6]
5
6
[0, 1, 2, 4, 5, 6]

迭代机制造成了4根本没被遍历到

list设计之初就不适合增加删除中间元素,有类似的需求根据具体情况具体分析选择使用list还是链表。

猜你喜欢

转载自blog.csdn.net/ftimes/article/details/119786473