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中的字典遍历备忘
Jan 17 Python
Python的Django框架中settings文件的部署建议
May 30 Python
python学习 流程控制语句详解
Jun 01 Python
Python安装Flask环境及简单应用示例
May 03 Python
python实现日志按天分割
Jul 22 Python
python科学计算之scipy——optimize用法
Nov 25 Python
python实现简单日志记录库glog的使用
Dec 13 Python
python判断变量是否为int、字符串、列表、元组、字典的方法详解
Feb 13 Python
Python偏函数Partial function使用方法实例详解
Jun 17 Python
python定时截屏实现
Nov 02 Python
pyqt5实现井字棋的示例代码
Dec 07 Python
python not运算符的实例用法
Jun 30 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
动态新闻发布的实现及其技巧
2006/10/09 PHP
PHP数组对比函数,存在交集则返回真,否则返回假
2011/02/03 PHP
非常好用的两个PHP函数 serialize()和unserialize()
2012/02/04 PHP
PHP 应用容器化以及部署方法
2018/02/12 PHP
Mootools 1.2教程 选项卡效果(Tabs)
2009/09/15 Javascript
javascript操作cookie的文章(设置,删除cookies)
2010/04/01 Javascript
jquery创建一个新的节点对象(自定义结构/内容)的好方法
2013/01/21 Javascript
js给页面加style无效果的解决方法
2014/01/20 Javascript
Javascript的setTimeout()使用闭包特性时需要注意的问题
2014/09/23 Javascript
让IE8浏览器支持function.bind()方法
2014/10/16 Javascript
深入理解JavaScript系列(38):设计模式之职责链模式详解
2015/03/04 Javascript
javascript合并表格单元格实例代码
2016/01/03 Javascript
JS模拟实现ECMAScript5新增的数组方法
2017/03/20 Javascript
vue2.0实现分页组件的实例代码
2017/06/22 Javascript
JS实现的按钮点击颜色切换功能示例
2017/10/19 Javascript
jquery获取select选中值的文本,并赋值给另一个输入框的方法
2018/08/21 jQuery
JS实现可针对算术表达式求值的计算器功能示例
2018/09/04 Javascript
Vue.js + Nuxt.js 项目中使用 Vee-validate 表单校验
2019/04/22 Javascript
简单了解vue中的v-if和v-show的区别
2019/10/08 Javascript
vue 动态表单开发方法案例详解
2019/12/02 Javascript
pygame游戏之旅 游戏中添加显示文字
2018/11/20 Python
如何通过python实现人脸识别验证
2020/01/17 Python
Python迭代器Iterable判断方法解析
2020/03/16 Python
Python Selenium实现无可视化界面过程解析
2020/08/25 Python
Python可以用来做什么
2020/11/23 Python
CSS教程:CSS3圆角属性
2009/04/02 HTML / CSS
CSS3的calc()做响应模式布局的实现方法
2017/09/06 HTML / CSS
Silk’n激光脱毛器官网:silkn.com
2016/10/06 全球购物
彪马香港官方网上商店:PUMA香港
2020/12/06 全球购物
SQL面试题
2013/12/09 面试题
酒店个人培训自我鉴定
2013/12/11 职场文书
和睦家庭事迹
2014/05/14 职场文书
致800米运动员广播稿(10篇)
2014/10/17 职场文书
诚实守信主题班会
2015/08/13 职场文书
python中Tkinter 窗口之输入框和文本框的实现
2021/04/12 Python
python实现双链表
2022/05/25 Python