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中的列表推导浅析
Apr 26 Python
Python通过解析网页实现看报程序的方法
Aug 04 Python
Python爬虫包 BeautifulSoup  递归抓取实例详解
Jan 28 Python
python中如何正确使用正则表达式的详细模式(Verbose mode expression)
Nov 08 Python
python解决字符串倒序输出的问题
Jun 25 Python
python中正则表达式 re.findall 用法
Oct 23 Python
Python matplotlib通过plt.scatter画空心圆标记出特定的点方法
Dec 13 Python
ERLANG和PYTHON互通实现过程详解
Jul 05 Python
keras模型保存为tensorflow的二进制模型方式
May 25 Python
Python爬虫之Selenium鼠标事件的实现
Dec 04 Python
Pycharm-community-2020.2.3 社区版安装教程图文详解
Dec 08 Python
python如何修改文件时间属性
Feb 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
PHP 自定义错误处理函数的使用详解
2013/05/10 PHP
PHP错误WARNING: SESSION_START() [FUNCTION.SESSION-START]解决方法
2014/05/04 PHP
Laravel最佳分割路由文件(routes.php)的方式
2016/08/04 PHP
CSS中简写属性要注意TRouBLe的顺序问题(避免踩坑)
2021/03/09 HTML / CSS
js 中 document.createEvent的用法
2010/08/29 Javascript
如何使用JS获取IE上传文件路径(IE7,8)
2013/07/08 Javascript
类似天猫商品详情随浏览器移动的示例代码
2014/02/27 Javascript
Bootstrap中定制LESS-颜色及导航条(推荐)
2016/11/21 Javascript
利用js查找数组中指定元素并返回该元素的所有索引示例
2017/03/29 Javascript
利用JS制作万年历的方法
2017/08/16 Javascript
基于JavaScript 性能优化技巧心得(分享)
2017/12/11 Javascript
jquery无缝图片轮播组件封装
2020/11/25 jQuery
浅谈一种让小程序支持JSX语法的新思路
2019/06/16 Javascript
在React中写一个Animation组件为组件进入和离开加上动画/过度效果
2019/06/24 Javascript
[19:24]DOTA2客户端使用指南 一分钟快速设置轻松超神
2013/09/24 DOTA
[13:39]2014 DOTA2华西杯精英邀请赛 5 25 NewBee VS DK第一场
2014/05/26 DOTA
一则python3的简单爬虫代码
2014/05/26 Python
Python获取CPU、内存使用率以及网络使用状态代码
2018/02/08 Python
matplotlib savefig 保存图片大小的实例
2018/05/24 Python
Python面向对象程序设计多继承和多态用法示例
2019/04/08 Python
Pytorch 实现权重初始化
2019/12/31 Python
python3.8与pyinstaller冲突问题的快速解决方法
2020/01/16 Python
Django中F函数的使用示例代码详解
2020/07/06 Python
python3.7中安装paddleocr及paddlepaddle包的多种方法
2020/11/27 Python
一款css实现的鼠标经过按钮的特效
2014/09/11 HTML / CSS
匡威帆布鞋美国官网:Converse美国
2016/08/22 全球购物
关于VPN
2012/06/10 面试题
项目经理任命书内容
2014/06/06 职场文书
国际贸易本科毕业生求职信
2014/09/26 职场文书
初中生旷课检讨书范文
2014/10/06 职场文书
表扬通报怎么写
2015/01/16 职场文书
违反纪律检讨书范文
2015/05/07 职场文书
岁月神偷观后感
2015/06/11 职场文书
2015年秋学期教研工作总结
2015/10/14 职场文书
java设计模式--原型模式详解
2021/07/21 Java/Android
vue el-table实现递归嵌套的示例代码
2022/08/14 Vue.js