积涓流之势,成汪洋之姿。
对于列表这种数据容器,对其中元素进行筛选并处理时很容易想到用for循环去逐个处理,还可以叠加上判断语句逐一对列表中的成员进行判断。 介于此,我在遍历列表元素进行判断删除时出现了如下场景:
问题代码: (s1,s2,s3这三个变量的此时的值为"","","hello-world" 其前面部分代码过于冗长且与出错部分无关,故不再copy)
slist = [s1, s2 ,s3]
for st in slist:
if st == "":
slist.remove(st)
return slist
分析出错过程并寻找原因:
(1)这是初试状态,通过在for循环中进行if判断是否为特定字符串(此处为空字符串),如果是进行相应处理。
(2)此时单步调试正常,使用list.remove(element)找到列表中相应元素(此时为空字符串)并删除,删除了下标为0(注意)的第一个空字符串元素,然后在循环内继续进行判断,如此往复
(3)继续单步调试,会发现下一个要判断的元素是“hello—world”,而不是本该被处理原slist的第二个元素""(空字符串),第二个元素直接被跳过了!!!!
(4)最后将被处理后的slist列表打印则会发现,原slist中的第二个元素竟然“幸存”下来!for循环难道开了小差,漏了这个老6?
笔者也是个萌新宝宝,看到这个结果实在是摸不着头脑,顿时感觉这个世界套路太多,不太友善(咳咳,扯远了)
就在我百思不得其解之际,无意间翻看了csdn其他大佬的学习笔记(链接放在最后,需要自取),终于找到了原因。
原来,for循环在运行过程中,会使用一个指针来标记当前正在处理的元素的位置,而当一个元素(下标为0)被处理完成之后,指针所记录的下标会自动“加一”去处理“下一个”元素,但是此时由于slist列表中的第一个元素被删除,原先的第二的元素变成了第一个元素,此时它的下标减一变成了0,后面的元素以次类推,下标均减一,但是for循环指针的下标并没有跟随这一调整而减一,for循环指针对应得下标值仍然为1,而此时下标为1的元素是初试状态slist列表的第三个元素(初始下标为2,此时应为第一个元素被删除而下标变成了1),所在实际的处理过程中“二号玩家”变成了老6光荣地苟到了最后(原slist列表第二个元素实际上根本没有参与到for循环地遍历过程中,而是由于下标的变动跳出了for循环,未被for循环所处理)
修正及其处理方法:
借鉴链接中提到的方法,我们可以额外采用一个列表(这个用来标记的列表称之为列表2,原列表称为列表1)来专门记录所要删除的元素的下标,而先不对列表1(原列表)进行删除操作,只是查找出所要删除的元素相对应的下标,并记录到列表2中,(此时因为没有元素的增删操作,下标与元素的对应关系一致保持不变),待对列表1全部的元素进行查找、判断、记录后,通过另一个for循环集中进行删除,实验结果如下图所示:
可以看到列表中所有空字符串均被删除,结果打印输出正确
至于其他的方法笔者还在整理中,待后续补充至此片中来。
文中提及的csdn链接:https://blog.csdn.net/weixin_39722188/article/details/111628974
标签:slist,下标,删除,python,元素,列表,循环 From: https://www.cnblogs.com/sure-codingspace/p/17565973.html