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 相关文章推荐
详解JavaScript编程中的window与window.screen对象
Oct 26 Python
Python实现简单字典树的方法
Apr 29 Python
Python中第三方库Requests库的高级用法详解
Mar 12 Python
Python PyQt5标准对话框用法示例
Aug 23 Python
深入理解python中sort()与sorted()的区别
Aug 29 Python
详解Python列表赋值复制深拷贝及5种浅拷贝
May 15 Python
python代码编写计算器小程序
Mar 30 Python
pycharm配置git(图文教程)
Aug 16 Python
python_matplotlib改变横坐标和纵坐标上的刻度(ticks)方式
May 16 Python
opencv 形态学变换(开运算,闭运算,梯度运算)
Jul 07 Python
Python浮点型(float)运算结果不正确的解决方案
Sep 22 Python
只用40行Python代码就能写出pdf转word小工具
May 31 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
文件上传之SWFUpload插件(代码)
2015/07/30 PHP
PHP与Java对比学习日期时间函数
2016/07/03 PHP
早该知道的7个JavaScript技巧
2013/03/27 Javascript
javascript清空table表格的方法
2015/05/14 Javascript
node.js实现端口转发
2016/04/14 Javascript
BootStrap智能表单实战系列(三)分块表单配置详解
2016/06/13 Javascript
深入理解JavaScript中的并行处理
2016/09/22 Javascript
原生JavaScript实现Tooltip浮动提示框特效
2017/03/07 Javascript
基于bootstrap实现bootstrap中文网巨幕效果
2017/05/02 Javascript
基于JavaScript实现选项卡效果
2017/07/21 Javascript
BootStrap模态框和select2合用时input无法获取焦点的解决方法
2017/09/01 Javascript
在vue项目创建的后初始化首次使用stylus安装方法分享
2018/01/25 Javascript
基于游标的分页接口实现代码示例
2018/11/12 Javascript
React通过redux-persist持久化数据存储的方法示例
2019/02/14 Javascript
泛谈JS逻辑判断选择器 || &&
2019/05/24 Javascript
vue实现一个矩形标记区域(rectangle marker)的方法
2020/10/28 Javascript
jQuery实现增删改查
2020/12/22 jQuery
[01:31]DOTA2上海特级锦标赛 SECRET战队完整宣传片
2016/03/16 DOTA
[01:30:55]VG vs Mineski Supermajor 败者组 BO3 第三场 6.6
2018/06/07 DOTA
python实现监控windows服务并自动启动服务示例
2014/04/17 Python
跟老齐学Python之dict()的操作方法
2014/09/24 Python
python简单猜数游戏实例
2015/07/09 Python
Python中列表list以及list与数组array的相互转换实现方法
2017/09/22 Python
解决python中使用plot画图,图不显示的问题
2018/07/04 Python
解决Pytorch 训练与测试时爆显存(out of memory)的问题
2019/08/20 Python
浅谈优化Django ORM中的性能问题
2020/07/09 Python
让IE6、IE7、IE8支持CSS3的脚本
2010/07/20 HTML / CSS
Jimmy Choo美国官网:周仰杰鞋子品牌
2018/06/08 全球购物
说说你所熟悉或听说过的j2ee中的几种常用模式?及对设计模式的一些看法
2012/05/24 面试题
期末评语大全
2014/05/04 职场文书
小平小道观后感
2015/06/09 职场文书
西安事变观后感
2015/06/12 职场文书
开票证明
2015/06/23 职场文书
员工担保书范本
2015/09/22 职场文书
PyTorch device与cuda.device用法
2022/04/03 Python
ORACLE中dbms_output.put_line输出问题的解决过程
2022/06/28 Oracle