专栏首页Python空间你所不知道的「删除」操作。

你所不知道的「删除」操作。

本文字数:1243 字

阅读本文大概需要:4 分钟

看到标题的时候你可能会想:“不就是删除么?这有什么好说的呢?”其实真的是这样么?

在 Python 中,有删除作用的一般是 del、remove 和 pop,相信很多人都用过,但是不是真的会有待商榷,下面我们先来看一个例子:

lst1 = [1,2,3,4]
lst2 = [1,2,3,4]
lst3 = [1,2,3,4]
lst4 = [1,2,3,4]

for i, j in enumerate(lst1):
   del j

for i, j in enumerate(lst2):
   lst2.remove(j)

for i, j in enumerate(lst3[:]):
   lst3.remove(j)

for i, j in enumerate(lst4):
   lst4.pop(i)

上述的代码运行完以后,你知道列表 lst1 ~ lst4 此时变成了什么吗?按照自己之前的理解,思考完毕以后请继续向下看:

>>> lst1
[1,2,3,4]
>>> lst2
[2,4]
>>> lst3
[]
>>> lst4
[2,4]

看了上面的结果,是不是觉的有点懵?为什么会输出 [2,4]?

很多人在用的时候就只是用,没有真正的去看到底用的原理是什么,就比如这里的「删除」,同样是叫「删除」就真的一样吗?所以在回答上面的疑问之前,我们先再看一下 del、remove 和 pop 的不同

「del list_name」 这个删除只是从本地或者全局命名空间中删除了 list_name,这就是为什么在上述代码的操作中 lst1 前后没有改变;「remove」是会删除第一个匹配到的指定值,而不是说特定的索引,如果没有找到指定值的话会抛出 ValueError 异常;最后的「pop」则会删除指定索引处的元素并且返回它,如果指定的索引为无效索引则抛出 IndexError 异常。

看了上面对于三者「删除」之间的不同,然后我再来解释「为什么输出是 [2,4]」就很好理解了:

Python 中列表迭代是按照索引进行的,所以当我们从 lst2 或者 lst4 中删除索引为0,也就是元素 1 的时候,列表就变成了 [2,3,4],对于列表中剩下的 2、3、4 元素来说,它们的索引从 1、2、3 变成了 0、1、2。由于下一次迭代将获取索引为 1 的值,也就是 3,因此元素 2 将被彻底的跳过(类似的情况会交替发生在列表中的每个元素上)。

现在我们明白了问题所在,在最后我想再补充一点:在文章最初,代码中「在迭代时修改对象」是一种很 stupid 的做法,正确的做法应该是迭代对象的副本,如 lst3[:] 这种做法才是我们应该学习的正确做法,因为 Python 为切片列表创建了新的对象:

>>> lst1 = [1,2,3,4]
>>> id(lst1)
4301259848
>>> id(lst1[:])
4301260040

本文分享自微信公众号 - Python空间(Devtogether)

原文出处及转载信息见文内详细说明,如有侵权,请联系 yunjia_community@tencent.com 删除。

原始发表时间:2019-01-29

本文参与腾讯云自媒体分享计划,欢迎正在阅读的你也加入,一起分享。

我来说两句

0 条评论
登录 后参与评论

相关文章

  • Python 标准库之 XML(下)

    隔了两天了,不知道你们还记得上一篇文章的内容不,如果不记得的话请移步 -- Python 标准库之 XML(上)。

    Rocky0429
  • 黑客们会用到哪些Python技术?

    Python已经成为漏洞开发领域的行业标准,读者会发现大多数概念验证工具都是用Python语言编写的(除了用Ruby写的安全漏洞检测工具)。Python允许开发...

    Rocky0429
  • [技巧篇] 创建百万级实例如何节省内存?

    在实际工作中,我们可能会面临创建百万级别量实例的这种情况,比如在某流行社交网络中,定义了用户类 User(id, name, sex, status, ...)...

    Rocky0429
  • 你所不知道的「删除」操作

    在 Python 中,有删除作用的一般是 del、remove 和 pop,相信很多人都用过,但是不是真的会有待商榷,下面我们先来看一个例子:

    不羁的程序员小王
  • 记一次对某非法站点从SQL注入到整站打包与本地搭建全过程

    如题,由于是在已知有一处sql注入的情况下才接手进行的后续操作,因此前面信息搜集则一笔带过。

    HACK学习
  • org.hibernate.MappingException: Could not determine type for: String, at table: Elec_Text, for colum

    org.hibernate.MappingException: Could not determine type for: String, at table: ...

    qubianzhong
  • 彻底解决分布式系统一致性问题

    首先本章内容参考《分布式服务架构》整理,思考和总结纯个人理解。 要想解决一致性问题,就要先搞明白,什么是一致性问题,一致性问题是...

    疯狂的KK
  • 研究发现:机器人假肢可以提供受控的触觉反馈

    失去手臂并不意味着失去所有的触觉,这要归功于机器人假肢,通过温和的电子反馈刺激神经。

    机器人网
  • 观点 | 哈哈,TensorFlow被吐槽了吧

    作者 | Nico 参与 | shawn 今天,一篇吐槽TensorFlow的文章在网上刷屏,到底是怎么回事呢?来看这位作者的抱怨有没有道理。 每隔几个月,我都...

    AI科技大本营
  • 交换与选择类排序

    各种排序算法所需辅助空间 1、 所有的简单排序方法(包括:直接插入、起泡和简单选择)和堆排序的空间复杂度为O(1);

    _DIY

扫码关注云+社区

领取腾讯云代金券