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中MYSQLdb出现乱码的解决方法
Oct 11 Python
Python3读取UTF-8文件及统计文件行数的方法
May 22 Python
python UNIX_TIMESTAMP时间处理方法分析
Apr 18 Python
Python编程实现双链表,栈,队列及二叉树的方法示例
Nov 01 Python
python pandas dataframe 行列选择,切片操作方法
Apr 10 Python
分享8个非常流行的 Python 可视化工具包
Jun 05 Python
Python + OpenCV 实现LBP特征提取的示例代码
Jul 11 Python
python 实现从高分辨图像上抠取图像块
Jan 02 Python
sklearn线性逻辑回归和非线性逻辑回归的实现
Jun 09 Python
在tensorflow下利用plt画论文中loss,acc等曲线图实例
Jun 15 Python
Python 创建TCP服务器的方法
Jul 28 Python
python热力图实现简单方法
Jan 29 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
在“咖啡之国”感受咖啡文化
2021/03/03 咖啡文化
我的论坛源代码(八)
2006/10/09 PHP
《PHP边学边教》(02.Apache+PHP环境配置――下篇)
2006/12/13 PHP
数据库查询记录php 多行多列显示
2009/08/15 PHP
php中eval函数的危害与正确禁用方法
2014/06/30 PHP
php获取指定数量随机字符串的方法
2017/02/06 PHP
PHP中关键字interface和implements详解
2017/06/14 PHP
Javascript中的变量使用说明
2010/05/18 Javascript
js弹出框轻量级插件jquery.boxy使用介绍
2013/01/15 Javascript
jQuery使用andSelf()来包含之前的选择集
2014/05/19 Javascript
JQuery实现样式设置、追加、移除与切换的方法
2015/06/11 Javascript
element ui 对话框el-dialog关闭事件详解
2018/02/26 Javascript
vue.js根据代码运行环境选择baseurl的方法
2018/02/28 Javascript
一个简单的node.js界面实现方法
2018/06/01 Javascript
vue日历/日程提醒/html5本地缓存功能
2019/09/02 Javascript
微信小程序request请求封装,验签代码实例
2019/12/04 Javascript
vue实现商品列表的添加删除实例讲解
2020/05/14 Javascript
Python记录详细调用堆栈日志的方法
2015/05/05 Python
python3+PyQt5实现自定义分数滑块部件
2018/04/24 Python
python 检查文件mime类型的方法
2018/12/08 Python
10行Python代码计算汽车数量的实现方法
2019/10/23 Python
Windows10下Tensorflow2.0 安装及环境配置教程(图文)
2019/11/21 Python
python FTP批量下载/删除/上传实例
2019/12/22 Python
python实现从尾到头打印单链表操作示例
2020/02/22 Python
Python IDLE或shell中切换路径的操作
2020/03/09 Python
Python模块相关知识点小结
2020/03/09 Python
python 子类调用父类的构造函数实例
2020/03/12 Python
5款实用的python 工具推荐
2020/10/13 Python
python利用proxybroker构建爬虫免费IP代理池的实现
2021/02/21 Python
介绍一下gcc特性
2012/01/20 面试题
保研推荐信
2014/05/09 职场文书
努力学习演讲稿
2014/05/10 职场文书
五年级学生评语大全
2014/12/26 职场文书
思想品德评语大全
2014/12/31 职场文书
商务代表岗位职责
2015/02/15 职场文书
python析构函数用法及注意事项
2021/06/22 Python