前言

初学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)正序循环时删除:

删除元素[2]之后,下一次循环的下标索引为2,但此时,里面存放的是[4],于是就把[3]给漏了。

2)倒序循环时删除

删除元素[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中list循环遍历删除数据的正确方法

本文地址: http://www.cppcns.com/jiaoben/python/271627.html

python list遍历删除_Python中list循环遍历删除数据的正确方法相关推荐

  1. python dict(zip)函数_python中zip()函数遍历多个列表方法

    在对列表的元素进行找寻时,会频繁的说到遍历的理念.对于复杂的遍历要求,如多个列表中查找就显然不适合用for循环.本篇所要带来的是zip() 函数的方法,能够对多个迭代器进行遍历.下面我们就python ...

  2. python os.walk遍历目录_python中os.walk()遍历目录中所有文件

    之前一直用判断目录和文件的递归方法来获取一个目录下的所有文件,后来发现python里面已经写好了这个函数,不需要自己递归获取了,记录下os.walk()函数的用法 目的:获取path下所有文件,返回由 ...

  3. python二维元组_python中读入二维csv格式的表格方法详解(以元组/列表形式表示)

    如何去读取一个没有表头的二维csv文件(如下图所示)? 并以元组的形式表现数据: ((1.0, 0.0, 3.0, 180.0), (2.0, 0.0, 2.0, 180.0), (3.0, 0.0, ...

  4. python安装pyecharts失败_Python中pyecharts安装及安装失败的解决方法

    pyecharts 是一个用于生成 Echarts 图表的类库.Echarts 是百度开源的一个数据可视化 JS 库.这篇文章重点给大家介绍pyecharts安装失败的处理方法,具体详情如下: pye ...

  5. python 返回函数 闭包_python中闭包Closure函数作为返回值的方法示例

    前言 首先看看闭包的概念:闭包(Closure)是词法闭包(Lexical Closure)的简称,是引用了自由变量的函数.这个被引用的自由变量将和这个函数一同存在,即使已经离开了创造它的环境也不例外 ...

  6. python input 文件路径_python – 将目录路径作为用户输入的正确方法是什么?

    下面是我尝试用来将目录路径作为用户的"原始输入"的代码片段.从用户输入后,我收到以下错误: Traceback (most recent call last): File &quo ...

  7. python遍历循环怎么理解_聊聊python中的循环遍历

    python之循环遍历 关于循环遍历大家都知道,不外乎for和while,今天我在这写点不一样的循环和遍历.在实践中有时会遇到删除列表中的元素,那么循环遍历列表删除指定元素该怎么做呢? 还是直接上代码 ...

  8. Python基础_第3章_Python中的循环结构

    Python基础_第3章_Python中的循环结构 文章目录 Python基础_第3章_Python中的循环结构 Python中的循环结构 一.回顾分支练习题 1.判断是否为一个合法三角形 2.求世界 ...

  9. python中for循环遍历列表的几种方法

    列表在使用过程中,经常需要遍历列表的所有元素,对每个元素执行相同的操作.今天介绍python中for循环遍历列表的几种方法. 方法1:使用for循环简单结构遍历 首先我们新建一个城市列表,然后分别展示 ...

最新文章

  1. Node.js服务器启用Gzip压缩
  2. tmux/screen里面如何用鼠标滚轮来卷动窗口内容
  3. 对抗 Google优势 微软考虑收购雅虎
  4. fastadmin弹框提示不起作用 confirm
  5. 架构设计贵在务实(转载)
  6. blender怎么移动骨骼_日本这款人形机器人竟是多个机器人乐队的前辈!拥有人类骨骼,还会击鼓...
  7. win10电脑黑屏只有鼠标箭头_电脑黑屏后屏幕只有鼠标怎么办呢?
  8. .Net Core2.1 秒杀项目一步步实现CI/CD(Centos7)系列二:k8s高可用集群搭建总结以及部署API到k8s...
  9. scala面试问题_Scala高级面试问答
  10. lvs负载均衡的调度算法和工作模式
  11. php怎么异步执行,php怎么实现异步
  12. Stolz定理及其证明
  13. 每个开发人员现在应该下载的十种必备工具!
  14. 转化二进制数的c语言程序,c语言实现二进制数转换为十进制
  15. uint_32定义的说明
  16. Linux USB设备热插拔检测
  17. 流媒体转发服务器系统,流媒体转发服务器配置
  18. Linux 防火墙策略——APF
  19. 笔记本 android,震惊:这个秘籍可以让笔记本同时拥有(mac/win/Android)系统
  20. Gartner2019年十大安全项目详解

热门文章

  1. Hive的索引操作【小结】
  2. 分布式文件系统之Tachyon是什么?
  3. leetcode 395. Longest Substring with At Least K Repeating Characters| 395. 至少有 K 个重复字符的最长子串(分治法)
  4. 【Java数据结构】自己实现一个HahMap(实现其put, toString, get方法)
  5. 网络协议之:一定要大写的SOCKS
  6. Python解释器和IPython
  7. 基本的Socket通信
  8. 1027 打印沙漏 (20分)——27行代码AC(结构清晰)
  9. 【详解】以下关于TCP/IP协议栈中协议和层次的对应关系正确的是()
  10. 比紫书优化,14行代码AC——例题 5-7 丑数(Ugly Numbers,UVa 136)——解题报告