鱼C论坛

 找回密码
 立即注册
查看: 1076|回复: 11

[已解决]关于遍历,为什么遍历不全

[复制链接]
发表于 2020-5-26 22:11:05 | 显示全部楼层 |阅读模式

马上注册,结交更多好友,享用更多功能^_^

您需要 登录 才可以下载或查看,没有账号?立即注册

x
请教大家个问题:
为什么用for去遍历一个列表里的元素,并对列表元素处理时,不能遍历完整:

举例:
list_test = [1,2,3,4,5,6,6,6]
for each in list_test:
        if each == 6:
                print("Six")

这样可以完成输出为
Six
Six
Six
这样的结果可以理解。

但是如果改成下面
list_test = [1,2,3,4,5,6,6,6]
for each in list_test:
        if each == 6:
                list_test.remove(6)
                print("Six")
                print(list_test)

输出结果:
Six
[1,2,3,4,5,6,6]

明显没有遍历完整,后面两个6也没有移除。
这是为什么呢?
如果可以完成全部元素的遍历,和后面的移除操作(不仅是移除,可能还会涉及到其他的操作。)

最佳答案
2020-5-27 10:40:50
对于可变类型对象的遍历,不建议在循环体内增删元素。因为可能会影响遍历。
就像你这个程序,在循环过程中删除元素,导致列表list_test长度变短,导致部分元素没有被遍历。
[1,2,3,4,5,6,6,6],第六次循环的时候遍历的是list_test[5],然后执行了remove操作,把下标5的元素删除了,原来下标为6的元素下标变成了5,在下次循环的时候,会遍历下标为6的元素,而实际上遍历的是原下标为7的元素。

若真想在循环体内修改遍历对象的话,遍历条件写成原列表的拷贝。这样,遍历的对象就是愿列表的一个拷贝,和你在循环体内修改的对象就不是同一个列表了。
list_test = [1,2,3,4,5,6,6,6]
for each in list_test[:]:
        if each == 6:
                list_test.remove(6)
                print("Six")
                print(list_test)
想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
回复

使用道具 举报

发表于 2020-5-26 22:18:49 | 显示全部楼层
本帖最后由 Twilight6 于 2020-5-26 22:53 编辑

你输出结果错了,应该是两次:
Six
[1,2,3,4,5,6,6]
Six
[1,2,3,4,5,6]

原列表是指 :[1,2,3,4,5,6,6,6]

因为你第一次遍历是按照 [1,2,3,4,5,6,6,6] 这个列表遍历的,然后遍历到第一个6时候,此时for指向的是原列表的第一个6

通过 remove  移除一个 6  得到列表 [1,2,3,4,5,6,6],此时因为第一个6被移除了,第二个6就会往前进一位,所以for指向了原列表的第二个 6

再一次 for 遍历就是列表 [1,2,3,4,5,6,6] 而继续从下一个6 开始,也就是第三个6,所以通过remove 再次移除一个 6 导致列表变成[1,2,3,4,5,6],这时候for循环已经到结尾了,因为列表长度被你remove变短了
想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
回复 支持 1 反对 0

使用道具 举报

发表于 2020-5-26 22:30:02 | 显示全部楼层
楼上正解
想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
回复 支持 反对

使用道具 举报

发表于 2020-5-26 22:44:54 | 显示全部楼层
Twilight6 发表于 2020-5-26 22:39
对的 第一次遇到的6 和最后一次遇到的6

删除的应该就是第一个和第二个,我刚刚好像说错了
因为代码里是remove(6),所以是从左往右找,然后就找到第一个和第二个六
到第三个的时候正好遍历完了
想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
回复 支持 反对

使用道具 举报

发表于 2020-5-26 22:45:42 | 显示全部楼层
本帖最后由 Twilight6 于 2020-5-26 22:54 编辑
_荟桐_ 发表于 2020-5-26 22:44
删除的应该就是第一个和第二个,我刚刚好像说错了
因为代码里是remove(6),所以是从左往右找 ...


对哦  我也懵了 remove是按顺序的!

我之前是对的...被你误导下,我以为我错了, 白白编辑了那么久,重新编辑了个错的,现在改回来了

看来知识点不够牢固啊我
想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
回复 支持 反对

使用道具 举报

发表于 2020-5-26 22:46:54 | 显示全部楼层
_荟桐_ 发表于 2020-5-26 22:44
删除的应该就是第一个和第二个,我刚刚好像说错了
因为代码里是remove(6),所以是从左往右找 ...

给自己整懵了
想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
回复 支持 反对

使用道具 举报

发表于 2020-5-26 22:56:57 | 显示全部楼层

我脑袋报MemoryError怎么解决
想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
回复 支持 反对

使用道具 举报

发表于 2020-5-26 22:57:55 | 显示全部楼层
_荟桐_ 发表于 2020-5-26 22:56
我脑袋报MemoryError怎么解决

同种错误在线求解
想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
回复 支持 反对

使用道具 举报

 楼主| 发表于 2020-5-27 03:56:00 | 显示全部楼层
Twilight6 发表于 2020-5-26 22:18
你输出结果错了,应该是两次:
Six
[1,2,3,4,5,6,6]

也就是for 循环每次遍历都要执行“for each in list_test”这个语句,而不是只执行其下面缩进的部分?一直以为只执行缩进的部分
想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
回复 支持 反对

使用道具 举报

发表于 2020-5-27 07:30:40 | 显示全部楼层
AndyYoung 发表于 2020-5-27 03:56
也就是for 循环每次遍历都要执行“for each in list_test”这个语句,而不是只执行其下面缩进的部分?一 ...

对啊每次都要....你这误解大了
想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
回复 支持 反对

使用道具 举报

发表于 2020-5-27 07:44:01 From FishC Mobile | 显示全部楼层
在遍历列表时,不要对元素进行增减变动
或者说,在循环时,不要对循环变量进行增减变动
想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
回复 支持 反对

使用道具 举报

发表于 2020-5-27 10:40:50 | 显示全部楼层    本楼为最佳答案   
对于可变类型对象的遍历,不建议在循环体内增删元素。因为可能会影响遍历。
就像你这个程序,在循环过程中删除元素,导致列表list_test长度变短,导致部分元素没有被遍历。
[1,2,3,4,5,6,6,6],第六次循环的时候遍历的是list_test[5],然后执行了remove操作,把下标5的元素删除了,原来下标为6的元素下标变成了5,在下次循环的时候,会遍历下标为6的元素,而实际上遍历的是原下标为7的元素。

若真想在循环体内修改遍历对象的话,遍历条件写成原列表的拷贝。这样,遍历的对象就是愿列表的一个拷贝,和你在循环体内修改的对象就不是同一个列表了。
list_test = [1,2,3,4,5,6,6,6]
for each in list_test[:]:
        if each == 6:
                list_test.remove(6)
                print("Six")
                print(list_test)
想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
回复 支持 反对

使用道具 举报

您需要登录后才可以回帖 登录 | 立即注册

本版积分规则

小黑屋|手机版|Archiver|鱼C工作室 ( 粤ICP备18085999号-1 | 粤公网安备 44051102000585号)

GMT+8, 2025-1-20 22:38

Powered by Discuz! X3.4

© 2001-2023 Discuz! Team.

快速回复 返回顶部 返回列表