python列表操作remove()遇到的坑 您所在的位置:网站首页 pyremove是删除嘛 python列表操作remove()遇到的坑

python列表操作remove()遇到的坑

2023-10-15 10:29| 来源: 网络整理| 查看: 265

如果你只是想知道解决方法不想知道为什么的话,直接在迭代的时候给列表后面加上[::-1]即可,然后就不用往后看了

前言

remove是列表删除元素的三剑客之一,因为他可以直接填写元素项,因此十分好用,我也很喜欢,其实上半年用列表的时候就遇到了报错这个问题,找到了解决方法,但是刚刚有同学问我remove删除元素删除不干净的问题,我想了想,还是写一篇博客吧。

案例介绍

我们创建一个列表,把里面的33和44删掉,每次循环打印一下元素,最后打印一下列表

ls = [11,22,33,44,55] for i in ls: print(i) if i == 33 or i == 44: ls.remove(i) print(ls)

执行结果

11 22 33 55 [11, 22, 44, 55]

首先我们可以看到,打印的元素根本就没有44,为什么呢?我们来详细一下

原因分析

其实在执行代码的时候,for循环的i依次代表每个元素,那大家有没有想过为什么可以取得到每一个元素呢?是怎么取的呢?这个迭代的底层原理是怎样的呢?我们一起来看看吧

for循环的这种遍历取值功能本质上是利用了迭代器的原理,如果你不知道什么是迭代器,没关系,我简单和你解释一下:

在这里插入图片描述 你创建的这个数据结构的内存空间是一定的,虽然会动态改变。迭代器就相当从第一个数据走到最后一个数据,每次做一次迭代,就会往后面迈一步,但如果你把前面的元素移除了,后面的元素就依次往前补,这就导致了你想删除的元素可能已经逃离到了安全区。

其实有同学可能会思考,这家伙不就是索引吗?其实也可以这么理解吧,但是这个索引最大值是动态改变的,你每次删除一个元素,这个索引的最大值就减一了。

来,咱们就以上面的例子为谈一下为啥会有问题

程序正老老实实的循环迭代,直到i为33的时候未删除33的时候列表是[11,22,33,44,55],删除了之后是[11,22,44,55]此时继续往后迭代,小箭头继续往后走,也就是遇到了55,44已经逃离到安全区了

那么为什么for循环会如此简洁?这是因为for循环底层我们做了:

第一,调用可迭代对象的__iter__方法,将goods转化为迭代器goods_iterator;第二,调用迭代器goods_iterator的__next__方法,返回出goods的第一个元素;第三,循环步骤2,直到迭代器内数据流全部输出,捕获异常() 解决方案

迭代列表的时候加上[::-1]

ls = [11,22,33,44,55] for i in ls[::-1]: print(i) if i == 33 or i == 44: ls.remove(i) print(ls)

输出结果

55 44 33 22 11 [11, 22, 55]

那为什么这样可以呢?因为我们的迭代是从最后开始的,依次往前,这样就不会出现后面元素移位到前面这一说了,因为我们删除就是从后往前删除的啊,可以好好吸收一下。



【本文地址】

公司简介

联系我们

今日新闻

    推荐新闻

    专题文章
      CopyRight 2018-2019 实验室设备网 版权所有