Python:不要在循环中删除元素
目录
01 有话要说
02 题目分析
01 有话要说
最近刷Python二级题,我实在没有想到真题里面居然出现循环中删除元素并判断的一道选择题。我觉得Python有一个很鲜明的特点就是:简洁清晰。说实在的,我不是很认可将这种题目放到考试里面去,本身在循环中删除元素就是大忌,但凡有点常识的人都不会这么干,更何况是学习python。如果我们阅读代码还需要翻阅大量的书籍,查阅网站才可以分析看懂这一行两行代码,我个人认为这种代码属于垃圾代码,真正牛x的代码应该是老少皆宜,应该在不丧失可读性的情况下去保证简洁。我觉得python之禅他应该奉为圭臬。
02 题目分析
当然,上面是我的小情绪,该分析的还是需要分析,下面是原题。
答案选C
首先需要了解for循环的原理:首先使用iiter()得到列表的可迭代对象,再使用next()方法对列表的可迭代对象取值,直到取完所有值。
如果你不明白迭代器这些,那也不是问题,这里通俗说一下就好你就明白了。对于列表,for循环,每取一个值,实际上都是先取索引(最初从0开始依次加1),然后根据索引找到对应的列表值返回,所以for循环呈现给我们的假象是依次取出每一个元素值。如果你还是不明白,那我们总明白for循环总是可以用while循环表示对吧,那我们就用while循环表现类似的效果(为了不增加难度,这里不对列表进行迭代等等操作)
num = [1, 2, 3, 4]
# 以下是for循环的过程(这实际并不是,只是类似的效果)
length = len(num)
first = 0
while first < length:
num_i = num[first] # num_i是取出的列表元素值
first += 1
# 上述类似于完成了for i in num中的取值i
所以呢,我们来分析题目。
先取索引0,然后得到值'A' ==> if判断发现不是'D',进入下一次循环
取索引1,然后得到值'B' ==> if判断发现不是'D',进入下一次循环
取索引2,然后得到值'C' ==> if判断发现不是'D',进入下一次循环
取索引3,然后得到值'D' ==> if判断发现就是是'D',使用remove()方法将第一个D删除。
取索引4,前面已经对列表进行了删除所以现在列表是['A','B','C','D','D'],那么按要求来,索引为4的值是目前列表中的第二个'D' ==> if判断发现就是'D',使用remove()方法将第一个'D'删除(remove方法永远只删从左往右遇见的第一个目标值)。
取索引5,前面已经对列表进行了两次删除所以现在列表是['A','B','C','D'],那么按要求来,索引为5的值不存在,所以取值失败退出for循环。
可能上面的过程分析你会有所疑虑,但是我想说,大体过程确实如此,只是没有将迭代等相关的知识容纳进去,但是它并不会影响你理解这道题为什么正确结果是D。
如果你需要分析,这里给出代码,就不过多解释了。
>>> num = ['A', 'B', 'C', 'D', 'D', 'D']
>>> num_iter = iter(num) # 得到num的迭代器
>>> next(num_iter) # 获取索引为0的值并返回,值为'A'
'A'
>>> next(num_iter) # 获取索引为1的值并返回,值为'B'
'B'
>>> next(num_iter) # 获取索引为2的值并返回,值为'C'
'C'
>>> next(num_iter) # 获取索引为3的值并返回,值为'D'
'D'
>>> num.remove('D') # if判断为True,删除第一个'D'
>>> next(num_iter) # 获取索引为4的值并返回,由于上一行对列表进行了删操作,所以新列表是['A', 'B', 'C', 'D', 'D'],获取的 是第二个'D'
'D'
>>> num.remove('D') # id判断为True,删除第一个'D'(remove删除从左往右遇见的第一个目标值)
>>> next(num_iter) # 获取索引为5的值并返回,由于上一行对列表进行了删操作,所以新列表是['A', 'B', 'C', 'D'],新列表没有索引5,所以取值失败,退出for循环
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
StopIteration
<p>炒茄子</p>