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读取网页内容的方法
Jul 30 Python
浅谈python类属性的访问、设置和删除方法
Jul 25 Python
Python入门教程之运算符与控制流
Aug 17 Python
在Python中pandas.DataFrame重置索引名称的实例
Nov 06 Python
Python使用LDAP做用户认证的方法
Jun 20 Python
简单了解python单例模式的几种写法
Jul 01 Python
安装Pycharm2019以及配置anconda教程的方法步骤
Nov 11 Python
Python使用Pandas读写Excel实例解析
Nov 19 Python
Python监控服务器实用工具psutil使用解析
Dec 19 Python
python3中确保枚举值代码分析
Dec 02 Python
Python Pandas常用函数方法总结
Jun 15 Python
pytorch分类模型绘制混淆矩阵以及可视化详解
Apr 07 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文件时顶部出现空白影响布局分析原因及解决办法
2013/01/11 PHP
Destoon实现多表查询示例
2014/08/21 PHP
PHP实现广度优先搜索算法(BFS,Broad First Search)详解
2017/09/16 PHP
PHP集成环境XAMPP的安装与配置
2018/11/13 PHP
JavaScript简单实现网页回到顶部功能
2013/11/12 Javascript
js键盘事件的keyCode
2014/07/29 Javascript
简介可以自动完成UI的AngularJS工具angular-smarty
2015/06/23 Javascript
详解Webwork中Action 调用的方法
2016/02/02 Javascript
JS控制FileUpload的上传文件类型实例代码
2016/10/07 Javascript
jQuery EasyUI 右键菜单--关闭标签/选项卡的简单实例
2016/10/10 Javascript
BootStrap Table 设置height表头与内容无法对齐的问题
2016/12/28 Javascript
微信小程序开发之Tabbar实例详解
2017/01/09 Javascript
AngularJS实现使用路由切换视图的方法
2017/01/24 Javascript
javascript 中的try catch应用总结
2017/04/01 Javascript
用vue和node写的简易购物车实现
2017/04/25 Javascript
一个简单的node.js界面实现方法
2018/06/01 Javascript
[04:29]DOTA2亚洲邀请赛小组赛第一日 TOP10精彩集锦
2015/02/01 DOTA
[01:19:35]DOTA2上海特级锦标赛主赛事日 - 3 败者组第三轮#2Fnatic VS OG第二局
2016/03/05 DOTA
Python文件和目录操作详解
2015/02/08 Python
python实现备份目录的方法
2015/08/03 Python
在PyCharm导航区中打开多个Project的关闭方法
2019/01/17 Python
详解Python网络框架Django和Scrapy安装指南
2019/04/01 Python
Pandas中Series和DataFrame的索引实现
2019/06/27 Python
全球性的在线鞋类品牌:Public Desire
2019/04/03 全球购物
存储过程的优缺点是什么
2015/01/10 面试题
不同浏览器创建XMLHttpRequest方法有什么不同
2014/11/17 面试题
高中生学习生活的自我评价
2013/10/09 职场文书
大学生四年生活自我鉴定
2013/11/21 职场文书
房地产推广策划方案
2014/05/19 职场文书
班主任2015新年寄语
2014/12/08 职场文书
离职感谢信怎么写
2015/01/22 职场文书
2015财务年度工作总结范文
2015/05/04 职场文书
女方家长婚礼答谢词
2015/09/29 职场文书
远程教育培训心得体会
2016/01/09 职场文书
详解Nginx启动失败的几种错误处理
2021/04/01 Servers
java中为什么说子类的构造方法默认访问的是父类的无参构造方法
2022/04/13 Java/Android