首先举个例子:
l=[1,1,1,2,3,4,5]
for i in l:
if i%2!=0: #把list中的奇数删除
l.remove(i)
print(l) #但是运行结果是[1, 2, 4],有奇数没被删掉。
#所以可以看出,循环删list的时候会导致下标错位,结果是不对的。
原因:
l=[1,1,1,2,3,4,5]
#0 1 2 3 4 5 6 (这里是对应的下标。)list根据下标取值操作。
#1,1,2,3,4,5 第一个下标是0,1/2的余数不是0,所以第一个1删掉,然后运行下标为1的,
# 但是此时原0位已经删掉看,后面顺序进位。第二个1的下标变成0,就被越过了。
解决方法:
l=[1,1,1,2,3,4,5]
l2=[1,1,1,2,3,4,5] #这样定义的两个ID地址是不一样的。
for i in l2: #循环l2,但是删的时候删l的内容。l2没改变过,所以下标也不会错位,所以删的l是显示正确的。
if i%2!=0:
l.remove(i)
print(l)
#list删除有两种:remove删除的是元素,pop删除的是下标
另一种,如果直接l2=l,这样运行结果也是[1, 2, 4]
l=[1,1,1,2,3,4,5]
l2=l #浅拷贝
print(id(l))
print(id(l2)) #l2=l这样赋值是浅拷贝,打印出来的ID地址是一样的
l2=copy.deepcopy(l) #这样赋值是深拷贝,打印出来的ID地址是不一样的。相当于在内存中重新开辟了一个地方存储。
l2=l.copy() #浅拷贝
#浅拷贝ID地址是一样的,所以list删除都是错误的。深拷贝ID地址不同,list删除是循环一个,删另一个。这样比较乱,所以list不要用循环删除。