当前位置: 移动技术网 > IT编程>脚本编程>Python > python篇-关于在for循环和列表结合中进行删除过程的陷阱详细解释

python篇-关于在for循环和列表结合中进行删除过程的陷阱详细解释

2020年07月26日  | 移动技术网IT编程  | 我要评论

一、原因

讲这个是因为很多初学者在遇到for循环和列表结合去处理问题的时候,往往会出现代码书写是没有问题的,但是就是无法执行正确答案,出现逻辑错误。但是找来找去就是不知道问题出在哪,实际上就是列表内部元素处理的问题。


给大家举个例子:

比如有一个简单的自然数构成的序列
[1, 2, 3, 4, 5, 6, 7, 8]

我有一个问题,要使用for循环和列表相关的知识点,将列表当中的奇数删除,留下偶数
好,那这样的话我就可以这么处理,先使用for循环遍历整个列表,在循环体中去判断,如果遍历到的元素跟2取余不等于0,那么就说这个数字是奇数,那在此条件下列表使用remove的方法删除具体元素

num = [1, 2, 3, 4, 5, 6, 7, 8]

for ele in num:
	if ele % 2 != 0:
		num.remove(ele)

print(num)

运行结果如下:
在这里插入图片描述
看上去好像是没问题的是吗?
如果大家觉得这就没问题了,那就掉陷阱里面了,如果我把序列改成整个样子

[1, 2, 3, 4, 5, 6, 7, 9]

那么,按照我们刚才的思路,还能只得出偶数吗?不用犹豫,既然我提出了这个问题,那肯定是不会只有偶数了,我们看结果
在这里插入图片描述
那么问题就来了,表面上看上去程序是没问题的啊,为什么我就修改了一个数据,结果就出问题了呢,听我慢慢道来


二、详细解释具体原因

我们来详细进入循环体中看看到底是怎么一回事
在这里插入图片描述

1、从下标为0的第一个元素开始,数字1是奇数,OK,程序做删除,但是删除之后,由于我们操作的是原列表,那么,删除1之后,后面的2,3,4,5,6,7,9这些元素的下标会统一减一

[1, 2, 3, 4, 5, 6, 7, 9]
[2, 3, 4, 5, 6, 7, 9]

那么此时,下标为0的元素就是2了,那么程序会认为,下标为0这个位置的元素已经遍历过,所以不对2进行判断,虽然2恰巧不是奇数,继续向下

2、遍历到下标为1的元素时,3是奇数,好,删除

[2, 3, 4, 5, 6, 7, 9]
[2, 4, 5, 6, 7, 9]

那么此时下标为1的元素就变成了数字4,恰好它不是奇数,继续向后

3、当程序遍历到下标为2的元素的时候,5是奇数,进行删除,此时下标为2的元素是6

[2, 4, 5, 6, 7, 9]
[2, 4, 6, 7, 9]

4、继续向后,遍历到下标为3,下标为3的元素是7,是奇数,进行删除

[2, 4, 6, 7, 9]
[2, 4, 6, 9]

5、此时下标为3的元素是9,但是程序认为已经遍历过了,不做处理,所以最后结果就是

[2, 4, 6, 9]

那真的是这样吗?我们把2,4,6分别替换成奇数,看看会不会不做处理
[1,11,3,13,5,15,7,9]

在这里插入图片描述
事实证明,确实如此,好,那既然知道了问题所在,那应该怎么解决呢?既然在从左向右依次遍历列表元素时,如果删除某个元素,那么后面还没有被遍历的元素下标势必会变动。那么我们就不从左向右了,从右向左逆序怎么样?

ok ,那就利用列表当中的切片操作,逆序遍历

在这里插入图片描述
完美解决问题,那么文章开头的那一组数据也就正常了
在这里插入图片描述


三、题外话

问题虽然解决了,但是代码还是多,俗话说人生苦短,我用python,能一行解决岂不更好

来一个列表推导式,直接把想要提取的数据直接拿出来,干脆,直截了当

在这里插入图片描述
有关列表推导式的知识点,小伙伴可以自行查找,不难理解

本文地址:https://blog.csdn.net/Z_love_u/article/details/107567551

如对本文有疑问, 点击进行留言回复!!

相关文章:

验证码:
移动技术网