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中Collections模块的Counter容器类使用教程
May 31 Python
Tensorflow之构建自己的图片数据集TFrecords的方法
Feb 07 Python
在pycharm中设置显示行数的方法
Jan 16 Python
python系列 文件操作的代码
Oct 06 Python
python os.path.isfile 的使用误区详解
Nov 29 Python
python默认参数调用方法解析
Feb 09 Python
简单介绍一下pyinstaller打包以及安全性的实现
Jun 02 Python
Anaconda的安装与虚拟环境建立
Nov 18 Python
Python用requests库爬取返回为空的解决办法
Feb 21 Python
只用40行Python代码就能写出pdf转word小工具
May 31 Python
拒绝盗图!教你怎么用python给图片加水印
Jun 04 Python
利用Python第三方库实现预测NBA比赛结果
Jun 21 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
FleaPHP的安全设置方法
2008/09/15 PHP
Zend Framework数据库操作技巧总结
2017/02/18 PHP
CI(CodeIgniter)框架实现图片上传的方法
2017/03/24 PHP
IIS 7.5 asp Session超时时间设置方法
2017/04/17 PHP
详细介绍8款超实用JavaScript框架
2013/10/25 Javascript
js获取select选中的option的text示例代码
2013/12/19 Javascript
js鼠标点击图片实现随机变换图片的方法
2015/02/16 Javascript
jQuery Mobile弹出窗、弹出层知识汇总
2016/01/05 Javascript
jquery实现input框获取焦点的方法
2017/02/06 Javascript
jQuery zTree树插件动态加载实例代码
2017/05/11 jQuery
nodejs实现连接mongodb数据库的方法示例
2018/03/15 NodeJs
js异步上传多张图片插件的使用方法
2018/10/22 Javascript
ES6的Fetch异步请求的实现方法
2018/12/07 Javascript
vue实现购物车抛物线小球动画效果的方法详解
2019/02/13 Javascript
TensorFlow.js 微信小程序插件开始支持模型缓存的方法
2020/02/21 Javascript
VSCode 添加自定义注释的方法(附带红色警戒经典注释风格)
2020/08/27 Javascript
[02:39]DOTA2国际邀请赛助威团西雅图第一天
2013/08/08 DOTA
[40:05]LGD vs Winstrike 2018国际邀请赛小组赛BO2 第二场 8.17
2018/08/18 DOTA
Python3.x和Python2.x的区别介绍
2013/02/12 Python
详解Python中的装饰器、闭包和functools的教程
2015/04/02 Python
python采集百度百科的方法
2015/06/05 Python
Python实现自定义顺序、排列写入数据到Excel的方法
2018/04/23 Python
Python3中关于cookie的创建与保存
2018/10/21 Python
Python3.6实现带有简单界面的有道翻译小程序
2019/04/16 Python
Python导入模块包原理及相关注意事项
2020/03/25 Python
巴西一家专门从事家居和装饰的连锁店:Camicado
2019/08/14 全球购物
惠而浦美国官网:Whirlpool.com
2021/01/19 全球购物
优秀应届毕业生推荐信
2014/02/18 职场文书
红色故事演讲稿
2014/05/22 职场文书
经济管理专业求职信
2014/06/09 职场文书
体育专业求职信
2014/07/16 职场文书
买房子个人收入证明
2014/10/12 职场文书
企业百日安全活动总结
2015/05/07 职场文书
2019行政前台转正申请书范文3篇
2019/08/15 职场文书
Nginx如何配置Http、Https、WS、WSS的方法步骤
2021/05/11 Servers
【海涛dota】偶遇拉娜娅 质量局德鲁伊第一视角解说
2022/04/01 DOTA