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+mysql实现简单的web程序
Sep 11 Python
详细解析Python中的变量的数据类型
May 13 Python
Python判断某个用户对某个文件的权限
Oct 13 Python
编写多线程Python服务器 最适合基础
Sep 14 Python
python微信撤回监测代码
Apr 29 Python
python实现日志按天分割
Jul 22 Python
Python安装及Pycharm安装使用教程图解
Sep 20 Python
使用Python画出小人发射爱心的代码
Nov 23 Python
python开发实例之python使用Websocket库开发简单聊天工具实例详解(python+Websocket+JS)
Mar 18 Python
Python-jenkins 获取job构建信息方式
May 12 Python
python 星号(*)的多种用途
Sep 21 Python
python文件名批量重命名脚本实例代码
Apr 22 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 实现进制转换(二进制、八进制、十六进制)互相转换实现代码
2010/10/22 PHP
php实现memcache缓存示例讲解
2013/12/04 PHP
基于php和mysql的简单的dao类实现crud操作功能
2014/01/27 PHP
php结合正则获取字符串中数字
2015/06/19 PHP
如何写php守护进程(Daemon)
2015/12/30 PHP
深入理解PHP JSON数组与对象
2016/07/19 PHP
Yii2中datetime类的使用
2016/12/17 PHP
当自定义数据属性为json格式字符串时jQuery的data api问题探讨
2013/02/18 Javascript
javascript对下拉列表框(select)的操作实例讲解
2013/11/29 Javascript
提取jquery的ready()方法单独使用示例
2014/03/25 Javascript
extjs_02_grid显示本地数据、显示跨域数据
2014/06/23 Javascript
纯javascript制作日历控件
2015/07/17 Javascript
Highcharts使用简例及异步动态读取数据
2015/12/30 Javascript
JS获取元素多层嵌套思路详解
2016/05/16 Javascript
BootStrap Typeahead自动补全插件实例代码
2016/08/10 Javascript
jQuery实现判断控件是否显示的方法
2017/01/11 Javascript
JS+HTML5实现上传图片预览效果完整实例【测试可用】
2017/04/20 Javascript
基于react后端渲染模板引擎noox发布使用
2018/01/11 Javascript
原生JS实现自定义下拉单选选择框功能
2018/10/12 Javascript
Vue实现剪贴板复制功能
2019/12/31 Javascript
Python新手在作用域方面经常容易碰到的问题
2015/04/03 Python
wxPython定时器wx.Timer简单应用实例
2015/06/03 Python
Python编程中的for循环语句学习教程
2015/10/14 Python
python如何查看系统网络流量的信息
2016/09/12 Python
Python中logging实例讲解
2019/01/17 Python
python 实现交换两个列表元素的位置示例
2019/06/26 Python
python常用排序算法的实现代码
2019/11/08 Python
python标准库OS模块函数列表与实例全解
2020/03/10 Python
CSS3实现同时执行倾斜和旋转的动画效果
2016/10/27 HTML / CSS
eHarmony英国:全球领先的认真恋爱约会平台之一
2020/11/16 全球购物
土木工程毕业生自荐信
2013/09/21 职场文书
2015年服务员工作总结
2015/04/08 职场文书
田径运动会广播稿
2015/08/19 职场文书
2016年主题党日活动总结
2016/04/05 职场文书
vue中this.$http.post()跨域和请求参数丢失的解决
2022/04/08 Vue.js
python数字图像处理之图像的批量处理
2022/06/28 Python