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 相关文章推荐
pyv8学习python和javascript变量进行交互
Dec 04 Python
python3.3教程之模拟百度登陆代码分享
Jan 16 Python
pyqt4教程之widget使用示例分享
Mar 07 Python
Python3搜索及替换文件中文本的方法
May 22 Python
Python写入CSV文件的方法
Jul 08 Python
基于python爬虫数据处理(详解)
Jun 10 Python
python实现决策树分类(2)
Aug 30 Python
Python编程实现tail-n查看日志文件的方法
Jul 08 Python
Django实现auth模块下的登录注册与注销功能
Oct 10 Python
python 实现多线程下载视频的代码
Nov 15 Python
python 项目目录结构设置
Feb 14 Python
用Python监控你的朋友都在浏览哪些网站?
May 27 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封装的数据库保存session功能类
2016/07/11 PHP
根据key删除数组中指定的元素实现方法
2017/03/02 PHP
PHP中递归的实现实例详解
2017/11/14 PHP
传智播客学习之java 反射
2009/11/22 Javascript
jQuery实现切换页面布局使用介绍
2011/10/09 Javascript
jQuery封装的获取Url中的Get参数示例
2013/11/26 Javascript
2014年50个程序员最适用的免费JQuery插件
2014/12/15 Javascript
jqueryUI里拖拽排序示例分析
2015/02/26 Javascript
JavaScript中的数据类型转换方法小结
2015/10/26 Javascript
node.js文件上传处理示例
2016/10/27 Javascript
node.js中EJS 模板快速入门教程
2017/05/08 Javascript
JS 实现banner图片轮播效果(鼠标事件)
2017/08/04 Javascript
深入理解JavaScript 箭头函数
2019/05/30 Javascript
js实现点击图片在屏幕中间弹出放大效果
2019/09/11 Javascript
vue 使用post/get 下载导出文件操作
2020/08/07 Javascript
[01:32]寻找你心中的那团火 DOTA2 TI9火焰传递活动今日开启
2019/05/16 DOTA
Python3控制路由器——使用requests重启极路由.py
2016/05/11 Python
Python自动化开发学习之三级菜单制作
2017/07/14 Python
关于python2 csv写入空白行的问题
2018/06/22 Python
pyqt5的QWebEngineView 使用模板的方法
2018/08/18 Python
python 2.7 检测一个网页是否能正常访问的方法
2018/12/26 Python
Python实现的对本地host127.0.0.1主机进行扫描端口功能示例
2019/02/15 Python
django的ORM模型的实现原理
2019/03/04 Python
python实现将视频按帧读取到自定义目录
2019/12/10 Python
python基于socket函数实现端口扫描
2020/05/28 Python
Pycharm2020.1安装无法启动问题即设置中文插件的方法
2020/08/07 Python
Python的Tqdm模块实现进度条配置
2021/02/24 Python
匡威爱尔兰官网:Converse爱尔兰
2019/06/09 全球购物
Servlet如何得到客户端机器的信息
2014/10/17 面试题
医学类导师推荐信范文
2013/11/19 职场文书
春季运动会广播稿大全
2014/02/19 职场文书
期末学生评语大全
2014/04/24 职场文书
师德先进个人事迹材料
2014/12/19 职场文书
教师工作证明范本
2015/06/12 职场文书
初中毕业生感言
2015/07/31 职场文书
小学教师教育随笔
2015/08/14 职场文书