# 如何理解使用for循环遍历lst与lst[:],如果使用remove更改列表结果会不同
'''
# 基础知识
一、lst与lst[:]的区别
lst[:]创建原始列表lst的副本。他们各自的改变不相互关联。
lst与lst[:]是独立的两个列表变量,对lst的增删改不会影响lst[:],对lst[:]的增删改也不会影响到lst
二、for循环按下标提取元素,不能后退。
三、remove删除列表元素时,列表元素的索引会发生变化
(这是因为Python底层列表是通过数组实现的,remove方法删除元素时需要挪动其他元素)
# 之所以有不同的结果在于for循环时,一个依据因remove语句下标不断变化的原生列表ls,一个是依据下标不变的原生列表的切片ls[:]
'''
# 列表中只有一个相同元素时
ls = ['a', 'b', 'c', 'd']
for i in ls:
#print(i) # 输出a b d 没有c,证明c因为下标改变而被忽略了,没被遍历到
if i == 'b':
ls.remove(i)
print(ls) # 结果['a', 'c', 'd']
'''
# for循环依据列表ls的下标进行遍历
第一次循环时,从列表ls下标为0的元素开始遍历,即i='a','a'!='b',所以此时lst还是['a', 'b', 'c', 'd']
第二次循环时,从列表ls下标为1的元素开始遍历,即i='b','b'=='b','b'被remove掉。元素'c','d'向前补位,他们的下标由2,3变成了1,2
此时列表ls变成['a', 'c', 'd']
第三次循环时,从列表ls下标为2的元素开始遍历,元素'c'因为下标由2变成了1而被略过了,此时下标为2的是元素'd',
即i='d','d'!='b',所以此时lst还是['a', 'c', 'd']
所以最后留下来的lst是:['a', 'c', 'd']
'''
# 列表中有两个相同元素时(列表中有两个或两个以上相同元素时,要注意元素下标的改变)
ls = ['a', 'b', 'b', 'c', 'd']
for i in ls:
#print(i) # 输出a b c d 缺少一个b,第二个b因为下标改变而被忽略了,没有遍历到
if i == 'b':
ls.remove(i)
print(ls) # 结果['a', 'b', 'c', 'd']
'''
# for循环依据列表ls的下标进行遍历
第一次循环时,从列表ls下标为0的元素开始遍历,即i='a','a'!='b',所以此时lst还是['a', 'b', 'b', 'c', 'd']
第二次循环时,从列表ls下标为1的元素开始遍历,即i='b','b'=='b','b'被remove掉,元素'b','c','d'向前补位,
他们的下标由2,3,4变成了1,2,3,此时列表ls变成['a', 'b', 'c', 'd']
第三次循环时,从列表ls下标为2的元素开始遍历,此时下标为2的元素'b'因为下标由2变成1就被略过了,此时下标为2的是元素'c',
即i='c','c'!='b',所以此时lst还是['a', 'b', 'c', 'd']
第四次循环时,从列表ls下标为3的元素开始遍历,即i='d','d'!='b',所以此时lst还是['a', 'b', 'c', 'd']
所以最后留下来的lst是:['a', 'b', 'c', 'd']
'''
#
ls = ['a', 'b', 'b', 'c', 'd']
for i in ls[:]:
if i == 'b':
ls.remove(i)
print(ls) # 结果['a', 'c', 'd']
'''
# for循环依据ls[:]切片形成的列表['a', 'b', 'b', 'c', 'd']下标的顺序遍历
# ls[:]不因ls的改变而改变,所以所有元素的下标均未因为列表ls中的元素被删除而改变
第一次循环时,从ls[:]切片形成的列表下标为0的元素开始遍历,即i='a','a'!='b',所以此时lst还是['a', 'b', 'b', 'c', 'd']
第二次循环时,从ls[:]切片形成的列表下标为1的元素开始遍历,即i='b','b'=='b','b'被remove掉,此时lst变成['a', 'b', 'c', 'd']
此时原列表ls['a', 'b', 'b', 'c', 'd']中,下标为1的元素'b'被remove掉了,
剩下的元素'b', 'c', 'd'他们的下标由2,3,4变成了1,2,3,但这不改变ls[:]切片列表的元素下标
第三次循环时,从ls[:]切片形成的列表下标为2的元素开始遍历,即i='b','b'=='b','b'被remove掉,此时lst变成['a', 'c', 'd']
第四次循环时,从ls[:]切片形成的列表下标为3的元素开始遍历,即i='c','c'!='b',所以此时lst还是['a', 'c', 'd']
第五次循环时,从ls[:]切片形成的列表下标为4的元素开始遍历,即i='d','d'!='b',所以此时lst还是['a', 'c', 'd']
所以最后留下来的lst是:['a', 'c', 'd']
'''
# 如何将列表中的某一个元素全部删除
lst = [1, 2, 3, 3, 3]
for num in lst[:]:
print(num, lst[:].index(num), id(num))
if num == 3:
lst.remove(num)
print(lst) # 结果[1, 2]
lst = [1, 2, 3, 3, 3]
for num in lst:
#print(num) # 输出结果1 2 3 3第二个3因为下标改变没被遍历到
if num == 3:
lst.remove(num)
print(lst) # 结果[1, 2, 3]
'''
第一次循环时,从列表lst下标为0的元素开始遍历,即num=1,1!=3,所以此时lst还是[1, 2, 3, 3, 3]
第二次循环时,从列表lst下标为1的元素开始遍历,即num=2,2!=3,所以此时lst还是[1, 2, 3, 3, 3]
第三次循环时,从列表lst下标为2的元素开始遍历,即num=3,3==3,3被remove掉,后面两个元素'3','3'向前补位,
他们的下标由3,4变成了2,3,此时lst变成[1, 2, 3, 3]
第四次循环时,从列表lst下标为3的元素开始遍历,即num=3,此时下标为2的元素3因为下标由3变成2就被略过了,
此时下标为3的是原下标为4的元素3,num=3,3==3,3被remove掉,所以此时lst变成[1, 2, 3]
所以最后留下来的lst是:[1, 2, 3]
'''
版权声明:本文为qianlixiushi原创文章,遵循 CC 4.0 BY-SA 版权协议,转载请附上原文出处链接和本声明。