前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
工具
TVP
发布
社区首页 >专栏 >你所不知道的「删除」操作。

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

作者头像
编程文青李狗蛋
发布2019-11-07 16:42:23
3040
发布2019-11-07 16:42:23
举报
本文字数:1243 字

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

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

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

代码语言:javascript
复制
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 此时变成了什么吗?按照自己之前的理解,思考完毕以后请继续向下看:

代码语言:javascript
复制
>>> 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 为切片列表创建了新的对象:

代码语言:javascript
复制
>>> lst1 = [1,2,3,4]
>>> id(lst1)
4301259848
>>> id(lst1[:])
4301260040
本文参与 腾讯云自媒体分享计划,分享自微信公众号。
原始发表:2019-01-29,如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 Python空间 微信公众号,前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文参与 腾讯云自媒体分享计划  ,欢迎热爱写作的你一起参与!

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档