python生成器表达式和列表解析


Posted in Python onMarch 10, 2016

绝大多数情况下,遍历一个集合都是为了对元素应用某个动作或是进行筛选。如果看过本文的第二部分,你应该还记得有内建函数map和filter提供了这些功能,但Python仍然为这些操作提供了语言级的支持。

(x+1 for x in lst) #生成器表达式,返回迭代器。外部的括号可在用于参数时省略。 
[x+1 for x in lst] #列表解析,返回list

如你所见,生成器表达式和列表解析(注:这里的翻译有很多种,比如列表展开、列表推导等等,指的是同一个意思)的区别很小,所以人们提到这个特性时,简单起见往往只描述成列表解析。然而由于返回迭代器时,并不是在一开始就计算所有的元素,这样能得到更多的灵活性并且可以避开很多不必要的计算,所以除非你明确希望返回列表,否则应该始终使用生成器表达式。接下来的文字里我就不区分这两种形式了:)

你也可以为列表解析提供if子句进行筛选:

(x+1 for x in lst if x!=0)

或者提供多条for子句进行嵌套循环,嵌套次序就是for子句的顺序:

((x, y) for x in range(3) for y in range(x))

列表解析就是鲜明的Pythonic。我常遇到两个使用列表解析的问题,本应归属于最佳实践,但这两个问题非常典型,所以不妨在这里提一下:

第一个问题是,因为对元素应用的动作太复杂,不能用一个表达式写出来,所以不使用列表解析。这是典型的思想没有转变的例子,如果我们将动作封装成函数,那不就是一个表达式了么?

第二个问题是,因为if子句里的条件需要计算,同时结果也需要进行同样的计算,不希望计算两遍,就像这样:

(x.doSomething() for x in lst if x.doSomething()>0)

这样写确实很糟糕,但组合一下列表解析即可解决:

(x for x in (y.doSomething() for y in lst) if x>0)

内部的列表解析变量其实也可以用x,但为清晰起见我们改成了y。或者更清楚的,可以写成两个表达式:

tmp = (x.doSomething() for x in lst)
(x for x in tmp if x > 0)

列表解析可以替代绝大多数需要用到map和filter的场合,可能正因为此,著名的静态检查工具pylint将map和filter的使用列为了警告。

Python 相关文章推荐
对于Python的Django框架部署的一些建议
Apr 09 Python
python实现简单点对点(p2p)聊天
Sep 13 Python
Python3多进程 multiprocessing 模块实例详解
Jun 11 Python
浅谈numpy生成数组的零值问题
Nov 12 Python
如何使用Flask-Migrate拓展数据库表结构
Jul 24 Python
使用Python实现 学生学籍管理系统
Nov 26 Python
python剪切视频与合并视频的实现
Mar 03 Python
Django User 模块之 AbstractUser 扩展详解
Mar 11 Python
python实现飞船游戏的纵向移动
Apr 24 Python
Python绘图之二维图与三维图详解
Aug 04 Python
Python 处理日期时间的Arrow库使用
Aug 18 Python
Python 实现键盘鼠标按键模拟
Nov 18 Python
python迭代器与生成器详解
Mar 10 #Python
Python装饰器基础详解
Mar 09 #Python
Python求算数平方根和约数的方法汇总
Mar 09 #Python
Python实现Linux命令xxd -i功能
Mar 06 #Python
基于Python实现一个简单的银行转账操作
Mar 06 #Python
Python切片知识解析
Mar 06 #Python
Django Admin实现上传图片校验功能
Mar 06 #Python
You might like
php中静态类与静态变量用法的区别分析
2015/01/15 PHP
php实现字符串首字母大写和单词首字母大写的方法
2015/03/14 PHP
通过Email发送PHP错误的方法
2015/07/20 PHP
php技术实现加载字体并保存成图片
2015/07/27 PHP
PHP unlink与rmdir删除目录及目录下所有文件实例代码
2018/02/07 PHP
thinkphp5使用无限极分类
2019/02/18 PHP
windows系统php环境安装swoole具体步骤
2021/03/04 PHP
js 绑定带参数的事件以及手动触发事件
2010/04/27 Javascript
缓动函数requestAnimationFrame 更好的实现浏览器经动画
2012/12/07 Javascript
3种不同方式的焦点图轮播特效分享
2013/10/30 Javascript
js纯数字逐一停止显示效果的实现代码
2016/03/16 Javascript
AngularJS自定义指令之复制指令实现方法
2017/05/18 Javascript
微信小程序 实现点击添加移除class
2017/06/12 Javascript
微信小程序分页加载的实例代码
2017/07/11 Javascript
重学JS 系列:聊聊继承(推荐)
2019/04/11 Javascript
jQuery zTree插件使用简单教程
2019/08/16 jQuery
python实现数值积分的Simpson方法实例分析
2015/06/05 Python
Linux-ubuntu16.04 Python3.5配置OpenCV3.2的方法
2018/04/02 Python
python3之模块psutil系统性能信息使用
2018/05/30 Python
Python时间差中seconds和total_seconds的区别详解
2019/12/26 Python
python 实现仿微信聊天时间格式化显示的代码
2020/04/17 Python
Python应用实现双指数函数及拟合代码实例
2020/06/19 Python
Django模板报TemplateDoesNotExist异常(亲测可行)
2020/12/18 Python
matplotlib运行时配置(Runtime Configuration,rc)参数rcParams解析
2021/01/05 Python
HTML5中使用postMessage实现两个网页间传递数据
2016/06/22 HTML / CSS
关于canvas绘制模糊问题的解决方法
2019/09/24 HTML / CSS
Mansur Gavriel官网:纽约市的一个设计品牌
2019/05/02 全球购物
了解AppleShare protocol(AppleShare协议)吗
2015/08/28 面试题
人力资源管理专业应届生求职信
2013/09/28 职场文书
关于人生的感言
2014/01/17 职场文书
大一学生的职业生涯规划书范文
2014/01/19 职场文书
简历里的自我评价范文
2014/02/24 职场文书
会计学专业求职信
2014/07/17 职场文书
领导班子党的群众路线教育实践活动对照检查材料
2014/09/25 职场文书
Python常用配置文件ini、json、yaml读写总结
2021/07/09 Python
Python IO文件管理的具体使用
2022/03/20 Python