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 相关文章推荐
Django中使用group_by的方法
May 26 Python
python更新列表的方法
Jul 28 Python
Python实现读取json文件到excel表
Nov 18 Python
python OpenCV学习笔记直方图反向投影的实现
Feb 07 Python
python 3调用百度OCR API实现剪贴板文字识别
Sep 04 Python
python实现汽车管理系统
Nov 30 Python
Python最小二乘法矩阵
Jan 02 Python
python实现感知器算法(批处理)
Jan 18 Python
Python同步遍历多个列表的示例
Feb 19 Python
python实现抖音点赞功能
Apr 07 Python
python tkinter canvas使用实例
Nov 04 Python
python实现模拟器爬取抖音评论数据的示例代码
Jan 06 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面向对象全攻略 (九)访问类型
2009/09/30 PHP
PHP闭包实例解析
2014/09/08 PHP
PHP使用fopen与file_get_contents读取文件实例分享
2016/03/04 PHP
php验证码生成器
2017/05/24 PHP
JavaScript 字符编码规则
2009/05/04 Javascript
jQuery lazyload 的重复加载错误以及修复方法
2010/11/19 Javascript
Iframe自适应高度绝对好使的代码 兼容IE,遨游,火狐
2011/01/27 Javascript
nodeType属性返回被选节点的节点类型介绍
2013/11/22 Javascript
js模拟hashtable的简单实例
2014/03/06 Javascript
跟我学习javascript的prototype原型和原型链
2015/11/18 Javascript
实现JavaScript高性能的数据存储
2016/12/11 Javascript
使用ionic切换页面卡顿的解决方法
2016/12/16 Javascript
详解vue-cli 脚手架项目-package.json
2017/07/04 Javascript
javascript 日期相减-在线教程(附代码)
2017/08/17 Javascript
vue router自动判断左右翻页转场动画效果
2017/10/10 Javascript
解决Vue2.0中使用less给元素添加背景图片出现的问题
2018/09/03 Javascript
vue实现多个echarts根据屏幕大小变化而变化实例
2020/07/19 Javascript
手把手教你如何编译打包video.js
2020/12/09 Javascript
Python函数式编程指南(一):函数式编程概述
2015/06/24 Python
python实现文本去重且不打乱原本顺序
2016/01/26 Python
使用py2exe在Windows下将Python程序转为exe文件
2016/03/04 Python
python 不同方式读取文件速度不同的实例
2018/11/09 Python
django使用LDAP验证的方法示例
2018/12/10 Python
用Python中的turtle模块画图两只小羊方法
2019/04/09 Python
详解python函数的闭包问题(内部函数与外部函数详述)
2019/05/17 Python
Kears+Opencv实现简单人脸识别
2019/08/28 Python
详解python os.path.exists判断文件或文件夹是否存在
2020/11/16 Python
python中remove函数的踩坑记录
2021/01/04 Python
scrapy-splash简单使用详解
2021/02/21 Python
使用CSS3编写灰阶滤镜来制作黑白照片效果的方法
2016/05/09 HTML / CSS
美国购买隐形眼镜网站:Lenses For Less
2020/07/05 全球购物
大学生求职简历的自我评价
2013/10/14 职场文书
统计学专业毕业生的自我评价分享
2013/11/28 职场文书
信用社主任竞聘演讲稿
2014/05/23 职场文书
酒店前台辞职书
2015/02/26 职场文书
小学教师暑期培训心得体会
2016/01/09 职场文书