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 相关文章推荐
Python3实现的腾讯微博自动发帖小工具
Nov 11 Python
Python实现的数据结构与算法之基本搜索详解
Apr 22 Python
Python使用正则表达式抓取网页图片的方法示例
Apr 21 Python
Python cookbook(数据结构与算法)找到最大或最小的N个元素实现方法示例
Feb 13 Python
python实现读取大文件并逐行写入另外一个文件
Apr 19 Python
Python基于FTP模块实现ftp文件上传操作示例
Apr 23 Python
Python 实现自动导入缺失的库
Oct 29 Python
基于python2.7实现图形密码生成器的实例代码
Nov 05 Python
python将音频进行变速的操作方法
Apr 08 Python
python同时遍历两个list用法说明
May 02 Python
Keras之fit_generator与train_on_batch用法
Jun 17 Python
python和opencv构建运动检测器的实现
Mar 03 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 连接mssql数据库 初学php笔记
2010/03/01 PHP
mcrypt启用 加密以及解密过程详细解析
2013/08/07 PHP
php实现计算百度地图坐标之间距离的方法
2016/05/05 PHP
ThinkPHP框架表单验证操作方法
2017/07/19 PHP
JavaScript中void(0)的具体含义解释
2007/02/27 Javascript
5分钟理解JavaScript中this用法分享
2013/11/09 Javascript
JS实现根据出生年月计算年龄
2014/01/10 Javascript
javascript给span标签赋值的方法
2015/11/26 Javascript
用move.js库实现百叶窗特效
2017/02/08 Javascript
JS html时钟制作代码分享
2017/03/03 Javascript
获取当前按钮或者html的ID名称实例(推荐)
2017/06/23 Javascript
JS中把函数作为另一函数的参数传递方法(总结)
2017/06/28 Javascript
JS实现闭包中的沙箱模式示例
2017/09/07 Javascript
NodeJs项目中关闭ESLint的方法
2018/08/09 NodeJs
Map与WeakMap类型在JavaScript中的使用详解
2020/11/18 Javascript
[04:17]DOTA2完美盛典,rOtk、BurNIng携手巴图演唱《倔强》
2017/11/28 DOTA
python 输出一个两行字符的变量
2009/02/05 Python
Python字典简介以及用法详解
2016/11/15 Python
Python实现的个人所得税计算器示例
2018/06/01 Python
快速解决pandas.read_csv()乱码的问题
2018/06/15 Python
Python JSON格式数据的提取和保存的实现
2019/03/22 Python
django一对多模型以及如何在前端实现详解
2019/07/24 Python
Python之关于类变量的两种赋值区别详解
2020/03/12 Python
python中return如何写
2020/06/18 Python
python获取百度热榜链接的实例方法
2020/08/25 Python
HTML5的结构和语义(5):内嵌媒体
2008/10/17 HTML / CSS
英国手机零售商:Metrofone
2019/03/18 全球购物
美团网旗下网上订餐平台:美团外卖
2020/03/05 全球购物
英文自荐信
2013/12/19 职场文书
铁路个人事迹材料
2014/01/30 职场文书
公益活动邀请函
2014/02/05 职场文书
2014公安机关纪律作风整顿思想汇报
2014/09/13 职场文书
采购内勤岗位职责
2015/04/13 职场文书
初中运动会前导词
2015/07/20 职场文书
python 机器学习的标准化、归一化、正则化、离散化和白化
2021/04/16 Python
Nginx文件已经存在全局反向代理问题排查记录
2022/07/15 Servers