Python中list循环遍历删除数据的正确方法


Posted in Python onSeptember 02, 2019

前言

初学Python,遇到过这样的问题,在遍历list的时候,删除符合条件的数据,可是总是报异常,代码如下:

num_list = [1, 2, 3, 4, 5]
print(num_list)

for i in range(len(num_list)):
 if num_list[i] == 2:
  num_list.pop(i)
 else:
  print(num_list[i])

print(num_list)

会报异常:IndexError: list index out of range

原因是在删除list中的元素后,list的实际长度变小了,但是循环次数没有减少,依然按照原来list的长度进行遍历,所以会造成索引溢出。

于是我修改了代码如下:

num_list = [1, 2, 3, 4, 5]
print(num_list)

for i in range(len(num_list)):
 if i >= len(num_list):
  break

 if num_list[i] == 2:
  num_list.pop(i)
 else:
  print(num_list[i])

print(num_list)

这回不会报异常了,但是打印结果如下:

[1, 2, 3, 4, 5]
1
4
5
[1, 3, 4, 5]
[Finished in 0.441s]

虽然最后,list中的元素[2]确实被删除掉了,但是,在循环中的打印结果不对,少打印了[3]。

思考了下,知道了原因,当符合条件,删除元素[2]之后,后面的元素全部往前移,于是[3, 4, 5]向前移动,那么元素[3]的索引,就变成了之前[2]的索引(现在[3]的下标索引变为1了),后面的元素以此类推。可是,下一次for循环的时候,是从下标索引2开始的,于是,取出了元素[4],就把[3]漏掉了。

把代码修改成如下,结果一样,丝毫没有改观:

num_list = [1, 2, 3, 4, 5]
print(num_list)

for item in num_list:
 if item == 2:
  num_list.remove(item)
 else:
  print(item)

print(num_list)

既然知道了问题的根本原因所在,想要找到正确的方法,也并不难,于是我写了如下的代码:

num_list = [1, 2, 3, 4, 5]
print(num_list)

i = 0
while i < len(num_list):
 if num_list[i] == 2:
  num_list.pop(i)
  i -= 1
 else:
  print(num_list[i])

 i += 1

print(num_list)

执行结果,完全正确:

[1, 2, 3, 4, 5]
1
3
4
5
[1, 3, 4, 5]
[Finished in 0.536s]

我的做法是,既然用for循环不行,那就换个思路,用while循环来搞定。每次while循环的时候,都会去检查list的长度(i < len(num_list)),这样,就避免了索引溢出,然后,在符合条件,删除元素[2]之后,手动把当前下标索引-1,以使下一次循环的时候,通过-1后的下标索引取出来的元素是[3],而不是略过[3]。

当然,这还不是最优解,所以,我搜索到了通用的解决方案:1、倒序循环遍历;2、遍历拷贝的list,操作原始的list。

1、倒序循环:

num_list = [1, 2, 3, 4, 5]
print(num_list)

for i in range(len(num_list)-1, -1, -1):
 if num_list[i] == 2:
  num_list.pop(i)
 else:
  print(num_list[i])

print(num_list)

执行结果完全正确。那么,为何正序循环时删除就有问题,而倒序循环时删除就ok?额。。。。。。言语难表,还是画个丑图出来吧。

1)正序循环时删除:

Python中list循环遍历删除数据的正确方法

删除元素[2]之后,下一次循环的下标索引为2,但此时,里面存放的是[4],于是就把[3]给漏了。

2)倒序循环时删除

Python中list循环遍历删除数据的正确方法

删除元素[2]后,[3, 4, 5]往前挤,但是没关系,因为下一次循环的下标索引为0,里面存放的是[1],所以正是我们所期望的正确的元素值。

2、遍历拷贝的list,操作原始的list

num_list = [1, 2, 3, 4, 5]
print(num_list)

for item in num_list[:]:
 if item == 2:
  num_list.remove(item)
 else:
  print(item)

print(num_list)

原始的list是num_list,那么其实,num_list[:]是对原始的num_list的一个拷贝,是一个新的list,所以,我们遍历新的list,而删除原始的list中的元素,则既不会引起索引溢出,最后又能够得到想要的最终结果。此方法的缺点可能是,对于过大的list,拷贝后可能很占内存。那么对于这种情况,可以用倒序遍历的方法来实现。

总结

以上就是这篇文章的全部内容了,希望本文的内容对大家的学习或者工作具有一定的参考学习价值,谢谢大家对三水点靠木的支持。

Python 相关文章推荐
Python是编译运行的验证方法
Jan 30 Python
Python自动化运维和部署项目工具Fabric使用实例
Sep 18 Python
Python中的错误和异常处理简单操作示例【try-except用法】
Jul 25 Python
Python中字典的浅拷贝与深拷贝用法实例分析
Jan 02 Python
Python比较2个时间大小的实现方法
Apr 10 Python
Python爬虫常用小技巧之设置代理IP
Sep 13 Python
python opencv 图像边框(填充)添加及图像混合的实现方法(末尾实现类似幻灯片渐变的效果)
Mar 09 Python
Django-rest-framework中过滤器的定制实例
Apr 01 Python
django美化后台django-suit的安装配置操作
Jul 12 Python
python获取系统内存占用信息的实例方法
Jul 17 Python
python编写扎金花小程序的实例代码
Feb 23 Python
Python Pandas知识点之缺失值处理详解
May 11 Python
python中matplotlib条件背景颜色的实现
Sep 02 #Python
Python3批量移动指定文件到指定文件夹方法示例
Sep 02 #Python
Python流程控制 if else实现解析
Sep 02 #Python
Python 变量的创建过程详解
Sep 02 #Python
python脚本之一键移动自定格式文件方法实例
Sep 02 #Python
Python中zip()函数的简单用法举例
Sep 02 #Python
Python在OpenCV里实现极坐标变换功能
Sep 02 #Python
You might like
php获取访问者浏览页面的浏览器类型
2017/01/23 PHP
简单谈谈 php 文件锁
2017/02/19 PHP
PHP后期静态绑定之self::限制实例分析
2018/12/21 PHP
jquery 学习之二 属性(html()与html(val))
2010/11/25 Javascript
使用Jquery来实现可以输入值的下拉选单 雏型
2011/12/06 Javascript
轻松创建nodejs服务器(1):一个简单nodejs服务器例子
2014/12/18 NodeJs
jQuery链式操作实例分析
2015/11/16 Javascript
浅析ES6的八进制与二进制整数字面量
2016/08/30 Javascript
实例分析浏览器中“JavaScript解析器”的工作原理
2016/12/12 Javascript
jquery UI Datepicker时间控件冲突问题解决
2016/12/16 Javascript
weex里Vuex state使用storage持久化详解
2017/09/09 Javascript
JS实现用特殊符号替换字符串的中间部分区域的实例代码
2018/07/24 Javascript
浅谈React碰到v-if
2018/11/04 Javascript
js中事件对象和事件委托的介绍
2019/01/21 Javascript
基于node.js实现爬虫的讲解
2019/02/18 Javascript
js实现简单放大镜效果
2020/03/07 Javascript
解决antd日期选择组件,添加value就无法点击下一年和下一月问题
2020/10/29 Javascript
Vue项目如何引入bootstrap、elementUI、echarts
2020/11/26 Vue.js
[01:04:22]2018DOTA2亚洲邀请赛 3.31 小组赛 B组 IG vs EG
2018/04/01 DOTA
Python常见文件操作的函数示例代码
2011/11/15 Python
Python中用sleep()方法操作时间的教程
2015/05/22 Python
python实现kMeans算法
2017/12/21 Python
pygame实现俄罗斯方块游戏
2018/06/26 Python
python  创建一个保留重复值的列表的补码
2018/10/15 Python
PyQt5 实现给窗口设置背景图片的方法
2019/06/13 Python
Python爬虫 批量爬取下载抖音视频代码实例
2019/08/16 Python
git查看、创建、删除、本地、远程分支方法详解
2020/02/18 Python
Python基于模块Paramiko实现SSHv2协议
2020/04/28 Python
python保留格式汇总各部门excel内容的实现思路
2020/06/01 Python
喷漆工的岗位职责
2014/03/17 职场文书
家教广告词
2014/03/19 职场文书
创业者迈进成功第一步:如何写创业计划书?
2014/03/22 职场文书
廉洁自律演讲稿
2014/05/22 职场文书
保护动物的宣传语
2015/07/13 职场文书
养成教育主题班会
2015/08/13 职场文书
Python打包为exe详细教程
2021/05/18 Python