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装饰器验证配置文件示例
Feb 24 Python
跟老齐学Python之dict()的操作方法
Sep 24 Python
python中list常用操作实例详解
Jun 03 Python
Django框架使用富文本编辑器Uedit的方法分析
Jul 31 Python
浅谈Pycharm调用同级目录下的py脚本bug
Dec 03 Python
IntelliJ IDEA安装运行python插件方法
Dec 10 Python
python之当你发现QTimer不能用时的解决方法
Jun 21 Python
python实现爬虫抓取小说功能示例【抓取金庸小说】
Aug 09 Python
keras实现theano和tensorflow训练的模型相互转换
Jun 19 Python
python3从网络摄像机解析mjpeg http流的示例
Nov 13 Python
Python导入父文件夹中模块并读取当前文件夹内的资源
Nov 19 Python
Python OpenGL基本配置方式
May 20 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实现用户认证及管理完全源码
2007/03/11 PHP
微信网页授权(OAuth2.0) PHP 源码简单实现
2016/08/29 PHP
基于JQuery的Pager分页器实现代码
2010/07/17 Javascript
jQuery源码分析之jQuery中的循环技巧详解
2014/09/06 Javascript
JS动态创建元素的两种方法
2016/04/20 Javascript
jquery 判断selection range 是否在容器中的简单实例
2016/08/02 Javascript
浅谈时钟的生成(js手写简洁代码)
2016/08/20 Javascript
Bootstrap中的Dropdown下拉菜单更改为悬停(hover)触发
2016/08/31 Javascript
jQuery 获取遍历获取table中每一个tr中的第一个td的方法
2016/10/05 Javascript
js初始化验证实例详解
2016/11/26 Javascript
jQuery设计思想
2017/03/07 Javascript
VUE 全局变量的几种实现方式
2018/08/22 Javascript
NodeJs 文件系统操作模块fs使用方法详解
2018/11/26 NodeJs
Vue.js路由实现选项卡简单实例
2019/07/24 Javascript
vue实现评价星星功能
2020/06/30 Javascript
python实现应用程序在右键菜单中添加打开方式功能
2017/01/09 Python
python调用动态链接库的基本过程详解
2019/06/19 Python
Python上下文管理器用法及实例解析
2019/11/11 Python
python 一维二维插值实例
2020/04/22 Python
重写django的model下的objects模型管理器方式
2020/05/15 Python
python db类用法说明
2020/07/07 Python
Python 开发工具通过 agent 代理使用的方法
2020/09/27 Python
Canvas实现放大镜效果完整案例分析(附代码)
2020/11/26 HTML / CSS
Interrail法国:乘火车探索欧洲,最受欢迎的欧洲铁路通票
2019/08/27 全球购物
美国和加拿大计算机和电子产品购物网站:TigerDirect.com
2019/09/13 全球购物
医药专业应届毕业生求职信范文
2014/01/01 职场文书
写给爸爸的道歉信
2014/01/15 职场文书
2014信息技术专业毕业生自我评价
2014/01/17 职场文书
亮剑精神演讲稿
2014/05/23 职场文书
手术室护士节演讲稿
2014/08/27 职场文书
2014党委书记四风对照检查材料思想汇报
2014/09/21 职场文书
幼师辞职信范文
2015/02/27 职场文书
某某幼儿园的教育教学管理调研分析报告
2019/11/29 职场文书
解决Redis启动警告问题
2022/02/24 Redis
MongoDB误操作后使用oplog恢复数据
2022/04/11 MongoDB
java实现自定义时钟并实现走时功能
2022/06/21 Java/Android