当前位置:首页 > 科技  > 软件

Python陷阱-如何安全地删除列表元素?

来源: 责编: 时间:2024-01-10 17:24:01 439观看
导读一个常见的任务是在一个列表上迭代,并根据条件删除一些元素。本文将展示如何完成该任务的不同方法,同时展示一些需要避免的陷阱。假设我们需要修改列表a,并且必须删除所有不是偶数的项。首先实现辅助函数even(x)来确定一

一个常见的任务是在一个列表上迭代,并根据条件删除一些元素。本文将展示如何完成该任务的不同方法,同时展示一些需要避免的陷阱。fSb28资讯网——每日最新资讯28at.com

fSb28资讯网——每日最新资讯28at.com

假设我们需要修改列表a,并且必须删除所有不是偶数的项。首先实现辅助函数even(x)来确定一个数字x是否是偶数:fSb28资讯网——每日最新资讯28at.com

a = [1, 2, 2, 3, 4]def even(x):    return x % 2 == 0

方法1: 创建新列表,过滤元素

1a) 列表推导,创建新列表

使用列表推导创建一个新的列表,只包含你不想删除的元素,并把它分配回a:fSb28资讯网——每日最新资讯28at.com

a = [1, 2, 2, 3, 4]def even(x):    return x % 2 == 0# 列表推导,但创建了一个新的变量aa = [x for x in a if not even(x)]# --> a = [1, 3]print(a)

你可以在10个python小技巧文章中了解更多关于列表推导的知识。fSb28资讯网——每日最新资讯28at.com

1b) 列表推导,对a[:]赋值

上面的代码创建了一个新的变量a。我们也可以通过赋值给切片a[:]就地改变现有的列表。这种方法更有效率,如果有其他对a的引用需要反映变化的话,这种方法可能很有用。fSb28资讯网——每日最新资讯28at.com

a = [1, 2, 2, 3, 4]def even(x):    return x % 2 == 0# 列表推导,但赋值给a[:] 就地改变列表a[:] = [x for x in a if not even(x)]# --> a = [1, 3]print(a)

1c) 使用itertools.filterfalse()

itertools模块为非常有效的循环迭代提供了各种函数,并且提供了一种过滤元素的方法。fSb28资讯网——每日最新资讯28at.com

a = [1, 2, 2, 3, 4]def even(x):    return x % 2 == 0# 通过itertools 快速过滤from itertools import filterfalsea[:] = filterfalse(even, a)# --> a = [1, 3]print(a)

方法2:列表副本上迭代

如果你真的想保留for语法,那么需要在列表的副本上进行迭代(副本可以通过使用a[:]简单创建)。现在你可以在条件为True时从原始列表中删除元素:fSb28资讯网——每日最新资讯28at.com

a = [1, 2, 2, 3, 4]def even(x):    return x % 2 == 0# 注意是在列表副本a[:] 上循环for item in a[:]:    if even(item):        a.remove(item)# --> a = [1, 3]print(a)

常见陷阱

千万别在同一个列表上循环,并在迭代过程中修改它!fSb28资讯网——每日最新资讯28at.com

这和上面的代码是一样的,只是没有在副本上循环。删除一个元素将使所有后续元素向左移动一个位置,因此在下一次迭代中,一个元素将被跳过。这可能会导致不正确的结果:fSb28资讯网——每日最新资讯28at.com

a = [1, 2, 2, 3, 4]def even(x):    return x % 2 == 0# 直接在变量a上进行循环,没有在副本上for item in a:    if even(item):        a.remove(item)# --> a = [1, 2, 3] !!!print(a)

另外,在列表的循环过程中,千万不要修改索引!fSb28资讯网——每日最新资讯28at.com

这是不正确的,因为在循环中改变i不会影响下一次迭代中i的值。这个例子也会产生非预期的效果,甚至会导致IndexErrors,比如这里:fSb28资讯网——每日最新资讯28at.com

a = [1, 2, 2, 3, 4]def even(x):    return x % 2 == 0# 试图在循环在改变索引i,但出错!for i in range(len(a)):    if even(a[i]):        del a[i]        i -= 1# --> IndexError: list index out of rangeprint(a)

小节

通过上面的学习相信你现在可以安心地删除列表的部分元素.fSb28资讯网——每日最新资讯28at.com

本文链接:http://www.28at.com/showinfo-26-60375-0.htmlPython陷阱-如何安全地删除列表元素?

声明:本网页内容旨在传播知识,若有侵权等问题请及时与本网联系,我们将在第一时间删除处理。邮件:2376512515@qq.com

上一篇: Netflix《三体》真人剧集中文预告公开:共 8 集,3 月 21 日首播

下一篇: 面试官:禁用Cookie后Session还能用吗?

标签:
  • 热门焦点
  • 一加Ace2 Pro真机揭晓 钛空灰配色质感拉满

    终于,在经过了几波预热之后,一加Ace2 Pro的外观真机图在网上出现了。还是博主数码闲聊站曝光的,这次的外观设计还是延续了一加11的方案,只是细节上有了调整,例如新加入了钛空灰
  • 6月安卓手机性能榜:vivo/iQOO霸占旗舰排行榜前三

    2023年上半年已经正式过去了,我们也迎来了安兔兔V10版本,在新的骁龙8Gen3和天玑9300发布之前,性能榜的榜单大体会以骁龙8Gen2和天玑9200+为主,至于那颗3.36GHz的骁龙8Gen2领先
  • K8S | Service服务发现

    一、背景在微服务架构中,这里以开发环境「Dev」为基础来描述,在K8S集群中通常会开放:路由网关、注册中心、配置中心等相关服务,可以被集群外部访问;图片对于测试「Tes」环境或者
  • 如何正确使用:Has和:Nth-Last-Child

    我们可以用CSS检查,以了解一组元素的数量是否小于或等于一个数字。例如,一个拥有三个或更多子项的grid。你可能会想,为什么需要这样做呢?在某些情况下,一个组件或一个布局可能会
  • 一篇聊聊Go错误封装机制

    %w 是用于错误包装(Error Wrapping)的格式化动词。它是用于 fmt.Errorf 和 fmt.Sprintf 函数中的一个特殊格式化动词,用于将一个错误(或其他可打印的值)包装在一个新的错误中。使
  • .NET 程序的 GDI 句柄泄露的再反思

    一、背景1. 讲故事上个月我写过一篇 如何洞察 C# 程序的 GDI 句柄泄露 文章,当时用的是 GDIView + WinDbg 把问题搞定,前者用来定位泄露资源,后者用来定位泄露代码,后面有朋友反
  • 三星Galaxy Z Fold5官方渲染图曝光:13.4mm折叠厚度依旧感人

    据官方此前宣布,三星将于7月26日在韩国首尔举办Unpacked活动,届时将带来带来包括Galaxy Buds 3、Galaxy Watch 6、Galaxy Tab S9、Galaxy Z Flip 5、
  • iQOO Neo8系列或定档5月23日:首发天玑9200+ 安卓跑分王者

    去年10月,iQOO推出了iQOO Neo7系列机型,不仅搭载了天玑9000+,而且是同价位唯一一款天玑9000+直屏旗舰,一经上市便受到了用户的广泛关注。在时隔半年后,
  • SN570 NVMe SSD固态硬盘 价格与性能兼具

    SN570 NVMe SSD固态硬盘是西部数据发布的最新一代WD Blue系列的固态硬盘,不仅闪存技术更为精进,性能也得到了进一步的跃升。WD Blue SN570 NVMe SSD的包装外
Top