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实现图片滑动式验证识别方法
Nov 09 Python
TensorFlow模型保存和提取的方法
Mar 08 Python
python numpy格式化打印的实例
May 14 Python
Python FTP两个文件夹间的同步实例代码
May 25 Python
pyqt5之将textBrowser的内容写入txt文档的方法
Jun 21 Python
python 字典 setdefault()和get()方法比较详解
Aug 07 Python
Python创建数字列表的示例
Nov 28 Python
Tensorflow的常用矩阵生成方式
Jan 04 Python
使用Django和Postgres进行全文搜索的实例代码
Feb 13 Python
Python Socketserver实现FTP文件上传下载代码实例
Mar 27 Python
Python如何实现大型数组运算(使用NumPy)
Jul 24 Python
python语言中pandas字符串分割str.split()函数
Aug 05 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
destoon会员注册提示“数据校验失败(2)”解决方法
2014/06/21 PHP
制作安全性高的PHP网站的几个实用要点
2014/12/30 PHP
PHP 实现公历日期与农历日期的互转换
2017/09/13 PHP
微信支付之JSAPI公众号支付详解
2019/05/15 PHP
向当前style sheet中插入一个新的style实现方法
2013/04/01 Javascript
jQuery弹性滑动导航菜单实现思路及代码
2013/05/02 Javascript
Mac OS X 系统下安装和部署Egret引擎开发环境
2014/09/03 Javascript
js验证真实姓名与身份证号是否匹配
2015/10/13 Javascript
JS实现鼠标滑过链接改变网页背景颜色的方法
2015/10/20 Javascript
JavaScript实现简单的tab选项卡切换
2016/01/05 Javascript
使用AJAX实现Web页面进度条的实例分享
2016/05/06 Javascript
vue.js父组件使用外部对象的方法示例
2017/04/25 Javascript
Vue2 使用 Echarts 创建图表实例代码
2017/05/18 Javascript
JS实现仿饿了么在浏览器标签页失去焦点时网页Title改变
2017/06/01 Javascript
AngularJS中controller控制器继承的使用方法
2017/11/03 Javascript
Gulp实现静态网页模块化的方法详解
2018/01/09 Javascript
微信小程序实现YDUI的ScrollNav组件
2018/02/02 Javascript
Vue全局分页组件的实现代码
2018/08/10 Javascript
微信小程序解析富文本过程详解
2019/07/13 Javascript
python如何实现远程控制电脑(结合微信)
2015/12/21 Python
Flask和Django框架中自定义模型类的表名、父类相关问题分析
2018/07/19 Python
浅谈django orm 优化
2018/08/18 Python
使用python3实现操作串口详解
2019/01/01 Python
python 自动批量打开网页的示例
2019/02/21 Python
python的常见矩阵运算(小结)
2019/08/07 Python
Selenium基于PIL实现拼接滚动截图
2020/04/10 Python
8种常用的Python工具
2020/08/05 Python
python批量检查两个对应的txt文件的行数是否一致的实例代码
2020/10/31 Python
CSS3 完美实现圆角效果
2009/07/13 HTML / CSS
小学国庆节活动方案
2014/02/11 职场文书
高校自主招生自荐信2015
2015/03/04 职场文书
出国留学单位推荐信
2015/03/26 职场文书
公司保洁员管理制度
2015/08/04 职场文书
教师读书活动心得体会
2016/01/14 职场文书
Mac环境Nginx配置和访问本地静态资源的实现
2021/03/31 Servers
Python中json.load()和json.loads()有哪些区别
2021/06/07 Python