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 16 Python
python通过邮件服务器端口发送邮件的方法
Apr 30 Python
分享Python字符串关键点
Dec 13 Python
浅谈Python的异常处理
Jun 19 Python
python机器人行走步数问题的解决
Jan 29 Python
python3+mysql查询数据并通过邮件群发excel附件
Feb 24 Python
python仿evething的文件搜索器实例代码
May 13 Python
python简单实现矩阵的乘,加,转置和逆运算示例
Jul 10 Python
Python 如何优雅的将数字转化为时间格式的方法
Sep 26 Python
Python搭建代理IP池实现存储IP的方法
Oct 27 Python
python的scipy实现插值的示例代码
Nov 12 Python
java字符串格式化输出实例讲解
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
Home Coffee Roasting
2021/03/03 咖啡文化
我的论坛源代码(八)
2006/10/09 PHP
MySql 按时间段查询数据方法(实例说明)
2008/11/02 PHP
PHP中使用sleep造成mysql读取失败的案例和解决方法
2014/08/21 PHP
php检测图片主要颜色的方法
2015/07/01 PHP
yii2.0整合阿里云oss删除单个文件的方法
2017/09/19 PHP
深入浅析安装PhpStorm并激活的步骤详解
2020/09/17 PHP
JS代码格式化和语法着色V2
2006/10/14 Javascript
jQuery的链式调用浅析
2010/12/03 Javascript
关于js数组去重的问题小结
2014/01/24 Javascript
详解JavaScript中jQuery和Ajax以及JSONP的联合使用
2015/08/13 Javascript
理解JS事件循环
2016/01/07 Javascript
jQuery+css实现非常漂亮的水平导航菜单效果
2016/07/27 Javascript
浅谈javascript中的事件冒泡和事件捕获
2016/12/28 Javascript
EsLint入门学习教程
2017/02/17 Javascript
深入理解vue路由的使用
2017/03/24 Javascript
Vue组件的使用教程详解
2018/01/05 Javascript
Vue封装的可编辑表格插件方法
2018/08/28 Javascript
vue spa应用中的路由缓存问题与解决方案
2019/05/31 Javascript
[46:03]LGD vs VGJ.T 2018国际邀请赛小组赛BO2 第一场 8.16
2018/08/17 DOTA
python批量导出导入MySQL用户的方法
2013/11/15 Python
python分布式环境下的限流器的示例
2017/10/26 Python
python接口自动化(十六)--参数关联接口后传(详解)
2019/04/16 Python
Python控制Firefox方法总结
2019/06/03 Python
python可视化text()函数使用详解
2020/02/11 Python
python常用运维脚本实例小结
2020/02/14 Python
python实现一个猜拳游戏
2020/04/05 Python
值得收藏的HTML5资源(学习html5的朋友可以收藏下)
2010/07/20 HTML / CSS
Perfumetrader荷兰:香水、化妆品和护肤品在线商店
2017/09/15 全球购物
Maxpeedingrods美国:高性能汽车零件
2020/02/14 全球购物
2014年征兵标语
2014/06/20 职场文书
建筑学专业自荐书
2014/07/09 职场文书
元旦晚会开场白
2015/05/29 职场文书
换届选举主持词
2015/07/03 职场文书
2015大学党建带团建工作总结
2015/07/23 职场文书
Python matplotlib绘制雷达图
2022/04/13 Python