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 生成不重复的随机数的代码
May 15 Python
常用python编程模板汇总
Feb 12 Python
python 中random模块的常用方法总结
Jul 08 Python
Python实现动态加载模块、类、函数的方法分析
Jul 18 Python
python读取excel表格生成erlang数据
Aug 26 Python
python docx 中文字体设置的操作方法
May 08 Python
Python实现模拟浏览器请求及会话保持操作示例
Jul 30 Python
django做form表单的数据验证过程详解
Jul 26 Python
python实现的登录与提交表单数据功能示例
Sep 25 Python
Python使用enumerate获取迭代元素下标
Feb 03 Python
python设置环境变量的作用整理
Feb 17 Python
使用python求斐波那契数列中第n个数的值示例代码
Jul 26 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 正确解码javascript中通过escape编码后的字符
2010/01/28 PHP
php curl 登录163邮箱并抓取邮箱好友列表的代码(经测试)
2011/04/07 PHP
PHP 异步执行方法,模拟多线程的应用分析
2013/06/03 PHP
PHP输出XML到页面的3种方法详解
2013/06/06 PHP
PHP网页游戏学习之Xnova(ogame)源码解读(十四)
2014/06/26 PHP
tp5(thinkPHP5)操作mongoDB数据库的方法
2018/01/20 PHP
PHP实现的数据对象映射模式详解
2019/03/20 PHP
测试JavaScript字符串处理性能的代码
2009/12/07 Javascript
12款经典的白富美型—jquery图片轮播插件—前端开发必备
2013/01/08 Javascript
javascript打印大全(打印页面设置/打印预览代码)
2013/03/29 Javascript
jQuery中detach()方法用法实例
2014/12/25 Javascript
详解JavaScript中的客户端消息框架设计原理
2015/06/24 Javascript
js实现点击获取验证码倒计时效果
2021/01/28 Javascript
JQuery和HTML5 Canvas实现弹幕效果
2017/01/04 Javascript
利用Node.js对文件进行重命名
2017/03/12 Javascript
JavaScript实现简单的四则运算计算器完整实例
2017/04/28 Javascript
js使用i18n实现页面国际化的方法
2017/05/09 Javascript
使用ES6语法重构React代码详解
2017/05/09 Javascript
VueJs组件prop验证简单介绍
2017/09/12 Javascript
Vue中使用的EventBus有生命周期
2018/07/12 Javascript
详解vue引入子组件方法
2019/02/12 Javascript
jquery UI实现autocomplete在获取焦点时得到显示列表功能示例
2019/06/04 jQuery
利用百度echarts实现图表功能简单入门示例【附源码下载】
2019/06/10 Javascript
Python简单进程锁代码实例
2015/04/27 Python
python基于multiprocessing的多进程创建方法
2015/06/04 Python
Python 多进程和数据传递的理解
2017/10/09 Python
Django中使用haystack+whoosh实现搜索功能
2019/10/08 Python
python中从for循环延申到推导式的具体使用
2019/11/29 Python
NumPy统计函数的实现方法
2020/01/21 Python
keras自定义回调函数查看训练的loss和accuracy方式
2020/05/23 Python
学python爬虫能做什么
2020/07/29 Python
DogBuddy荷兰:找到你最完美的狗保姆
2019/04/17 全球购物
生态学毕业生自荐信
2013/10/27 职场文书
体育教师研修感悟
2015/11/18 职场文书
高三语文教学反思
2016/02/16 职场文书
担保书范文
2019/07/09 职场文书