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爬虫之打包生成exe文件
Nov 06 Python
判断网页编码的方法python版
Aug 12 Python
Python实现解析Bit Torrent种子文件内容的方法
Aug 29 Python
Python基于回溯法子集树模板解决m着色问题示例
Sep 07 Python
浅谈python中对于json写入txt文件的编码问题
Jun 07 Python
python中的字符串内部换行方法
Jul 19 Python
python的pip安装以及使用教程
Sep 18 Python
Python 正则表达式匹配字符串中的http链接方法
Dec 25 Python
python中for循环把字符串或者字典添加到列表的方法
Jul 20 Python
基于python实现从尾到头打印链表
Nov 02 Python
tensorflow 实现自定义layer并添加到计算图中
Feb 04 Python
python基础入门之字典和集合
Jun 13 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
laravel5.4生成验证码的实例讲解
2017/08/05 PHP
PHP接口类(interface)的定义、特点和应用示例
2020/05/18 PHP
jQuery与ExtJS之选择实例分析
2010/08/19 Javascript
自制基于jQuery的智能提示插件一枚
2011/02/18 Javascript
一行代码告别document.getElementById
2012/06/01 Javascript
Javascript Ajax异步读取RSS文档具体实现
2013/12/12 Javascript
JavaScript在for循环中绑定事件解决事件参数不同的情况
2014/01/20 Javascript
Node.js本地文件操作之文件拷贝与目录遍历的方法
2016/02/16 Javascript
使用jQuery Ajax 请求webservice来实现更简练的Ajax
2016/08/04 Javascript
jQuery得到多个值只能用取Class ,不能用取ID的方法
2016/12/04 Javascript
微信小程序 获取当前地理位置和经纬度实例代码
2016/12/05 Javascript
JS无缝滚动效果实现方法分析
2016/12/21 Javascript
原生JS实现圣旨卷轴展开效果
2017/03/06 Javascript
详解AngularJS2 Http服务
2017/06/26 Javascript
对mac下nodejs 更新到最新版本的最新方法(推荐)
2018/05/17 NodeJs
jQuery实现的简单拖拽功能示例【测试可用】
2018/08/14 jQuery
JavaScript遍历查找数组中最大值与最小值的方法示例
2019/05/24 Javascript
微信小程序绘制图片发送朋友圈
2019/07/25 Javascript
详解Vue Cli浏览器兼容性实践
2020/06/08 Javascript
使用wxPython获取系统剪贴板中的数据的教程
2015/05/06 Python
python中base64加密解密方法实例分析
2015/05/16 Python
Python中判断输入是否为数字的实现代码
2018/05/26 Python
解决Tensorflow使用pip安装后没有model目录的问题
2018/06/13 Python
python pip源配置,pip配置文件存放位置的方法
2019/07/12 Python
Django框架自定义模型管理器与元选项用法分析
2019/07/22 Python
python-docx文件定位读取过程(尝试替换)
2020/02/13 Python
在pycharm中实现删除bookmark
2020/02/14 Python
CSS3制作酷炫的三维相册效果
2016/07/01 HTML / CSS
html5文本内容_动力节点Java学院整理
2017/07/11 HTML / CSS
德国网上花店:Valentins
2018/08/15 全球购物
学习党课思想汇报
2013/12/29 职场文书
助人为乐模范事迹材料
2014/06/02 职场文书
无刑事犯罪记录证明
2014/09/18 职场文书
南阳市白酒市场的调查报告
2019/11/08 职场文书
详解CSS不受控制的position fixed
2021/05/25 HTML / CSS
Win11 22H2 2022怎么更新? 获得Win1122H22022版本升级技巧
2022/09/23 数码科技