python 安全地删除列表元素的方法


Posted in Python onMarch 16, 2022

前言:

看似简单的任务,往往隐藏陷阱!

一个常见的任务是在一个列表上迭代,并根据条件删除一些元素。本文将展示如何完成该任务的不同方法,同时展示一些需要避免的陷阱。

假设我们需要修改列表a,并且必须删除所有不是偶数的项。

首先实现辅助函数even(x)来确定一个数字x是否是偶数:

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

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

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

使用列表推导创建一个新的列表,只包含你不想删除的元素,并把它分配回a:

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)

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

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

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模块为非常有效的循环迭代提供了各种函数,并且提供了一种过滤元素的方法。

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

方法2:列表副本上迭代

如果你真的想保留for语法,那么需要在列表的副本上进行迭代(副本可以通过使用a[:]简单创建)。

现在你可以在条件为True时从原始列表中删除元素:

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)

常见陷阱

千万别在同一个列表上循环,并在迭代过程中修改它!

这和上面的代码是一样的,只是没有在副本上循环。删除一个元素将使所有后续元素向左移动一个位置,因此在下一次迭代中,一个元素将被跳过。

这可能会导致不正确的结果:

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)

另外,在列表的循环过程中,千万不要修改索引!

这是不正确的,因为在循环中改变i不会影响下一次迭代中i的值。这个例子也会产生非预期的效果,甚至会导致IndexErrors

比如这里:

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 range
print(a)

到此这篇关于python 安全地删除列表元素的方法的文章就介绍到这了,更多相关python 删除列表元素内容请搜索三水点靠木以前的文章或继续浏览下面的相关文章希望大家以后多多支持三水点靠木!

Python 相关文章推荐
Python编写简单的HTML页面合并脚本
Jul 11 Python
Python语言描述随机梯度下降法
Jan 04 Python
JSON文件及Python对JSON文件的读写操作
Oct 07 Python
Python类的继承用法示例
Jan 31 Python
django的ORM模型的实现原理
Mar 04 Python
Python生成器的使用方法和示例代码
Mar 04 Python
python定义类self用法实例解析
Jan 22 Python
pandas中read_csv、rolling、expanding用法详解
Apr 21 Python
python 最简单的实现适配器设计模式的示例
Jun 30 Python
Python如何定义有可选参数的元类
Jul 31 Python
详解python3类型注释annotations实用案例
Jan 20 Python
python中__slots__节约内存的具体做法
Jul 04 Python
python turtle绘制多边形和跳跃和改变速度特效
Python中的turtle画箭头,矩形,五角星
Mar 16 #Python
Python学习之异常中的finally使用详解
Mar 16 #Python
Python实现抖音热搜定时爬取功能
Mar 16 #Python
Python3的进程和线程你了解吗
Mar 16 #Python
python的列表生成式,生成器和generator对象你了解吗
Mar 16 #Python
bat批处理之字符串操作的实现
Mar 16 #Python
You might like
一段php加密解密的代码
2007/07/16 PHP
php流量统计功能的实现代码
2012/09/29 PHP
ECMall支持SSL连接邮件服务器的配置方法详解
2014/05/19 PHP
csdn 批量接受好友邀请
2009/02/19 Javascript
jQuery checkbox全选/取消全选实现代码
2009/11/14 Javascript
Javascript实现单张图片浏览
2014/12/18 Javascript
JavaScript 里的类数组对象
2015/04/08 Javascript
javascript解三阶幻方(九宫格)
2015/04/22 Javascript
jQuery结合ajax实现动态加载文本内容
2015/05/19 Javascript
下一代Bootstrap的5个特点 超酷炫!
2016/06/17 Javascript
关于Javascript中defer和async的区别总结
2016/09/20 Javascript
vue.js指令v-for使用及索引获取
2016/11/03 Javascript
JavaScript中localStorage对象存储方式实例分析
2017/01/12 Javascript
JS实现旋转木马式图片轮播效果
2017/01/18 Javascript
vueJs实现DOM加载完之后自动下拉到底部的实例代码
2018/08/31 Javascript
js设计模式之代理模式及订阅发布模式实例详解
2019/08/15 Javascript
[52:10]LGD vs Optic Supermajor小组赛D组胜者组决赛 BO3 第二场 6.3
2018/06/04 DOTA
Python多线程编程(五):死锁的形成
2015/04/05 Python
浅谈Python实现2种文件复制的方法
2018/01/19 Python
让Django支持Sql Server作后端数据库的方法
2018/05/29 Python
使用Django2快速开发Web项目的详细步骤
2019/01/06 Python
python画双y轴图像的示例代码
2019/07/07 Python
python ubplot使用方法解析
2020/01/10 Python
解决jupyter运行pyqt代码内核重启的问题
2020/04/16 Python
python基于exchange函数发送邮件过程详解
2020/11/06 Python
基于第一个PhoneGap(cordova)的应用详解
2013/05/03 HTML / CSS
国际化的太阳镜及太阳镜配件零售商:Sunglass Hut
2016/07/26 全球购物
瑞典时尚服装购物网站:Miinto.se
2017/10/30 全球购物
会计电算化个人求职信范文
2014/01/24 职场文书
《彭德怀和他的大黑骡子》教学反思
2014/04/12 职场文书
2014年办公室人员工作总结
2014/12/09 职场文书
邓小平文选读书笔记
2015/06/29 职场文书
离婚协议书格式范本
2016/03/18 职场文书
PHP面试题 wakeup魔法 Ezpop pop序列化与反序列化
2022/04/11 PHP
mysql幻读详解实例以及解决办法
2022/06/16 MySQL
JS前端监控采集用户行为的N种姿势
2022/07/23 Javascript