python 列表推导和生成器表达式的使用


Posted in Python onFebruary 01, 2021

序列

序列是指一组数据,按存放类型分为容器序列与扁平序列,按能否被修改分为不可变序列与可变序列。

容器序列与扁平序列

容器序列存放的是对象的引用,包括list、tuple、collections.deque。

扁平序列存放的是对象的值,包括str、bytes、bytearray、memoryview和array.array。

扁平序列的值是字符、字节和数值这种基础类型。

不可变序列与可变序列

不可变序列,包括tuple、str、bytes。

可变序列,包括list、bytearray、array.array、collection.deque、memoryview。

下图左边是父类,右边是子类,可以看出可变序列是从不可变序列继承来的,扩展了可变方法:

python 列表推导和生成器表达式的使用

列表推导

Python语言魅力在于简洁,这能从最常见的创建列表体现出来,比如我们想把字符串"abc"转换成新列表["a", "b", "c"],常规写法:

symbols = "abc"
codes = []
for symbol in symbols:
 codes.append(symbol)
print(codes) # ["a", "b", "c"]

用到了for循环和列表append方法。实际上可以不用append方法,直接:

symbols = "abc"
codes = [symbol for symbol in symbols]

这叫做列表推导,是更加Pythonic的写法。

无论是编写效率还是可阅读性,列表推导都更胜一筹,可以说是构建列表的快捷方式。但是不能滥用,通用原则是,如果列表推导的代码超过了两行,就要考虑用append了。这不是规定,完全可以凭借自我喜好来选择。

笛卡尔积是指多个序列中元素所有组合,我们用列表推导来实现笛卡尔积:

colors = ["black", "white"]
sizes = ["S", "M", "L"]
tshirts = [(color, size) for color in colors for size in sizes]

一行代码搞定!Life is short,use Python,list comprehension is wonderful,amazing。

注意这行代码有两个for循环,等价于:

for color in colors:
 for size in sizes:

运行结果是:

[('black', 'S'), ('black', 'M'), ('black', 'L'), ('white', 'S'), ('white', 'M'), ('white', 'L')]

如果换一下顺序:

[(color, size) for color in colors for size in sizes]

等价于:

for size in sizes:
 for color in colors:

运行结果是不同的,观察第2个元素:

[('black', 'S'), ('white', 'S'), ('black', 'M'), ('white', 'M'), ('black', 'L'), ('white', 'L')]

生成器表达式

一般接触到生成器时,都要讲yield关键字,看似有点复杂,然而却很简单,生成器就像列表推导一样,只不过是用来生成其他类型序列的,比如元组:

symbols = "abc"
codes = (symbol for symbol in symbols)

它的语法非常简单,把列表推导的中括号[]换成小括号(),就可以了。

语法相似,本质上却有很大区别,我们试着用生成器表达式来实现笛卡尔积,看看会有什么变化:

colors = ["black", "white"]
sizes = ["S", "M", "L"]
tshirts = ((color, size) for color in colors for size in sizes)

运行结果是:

<generator object <genexpr> at 0x000001FD57D2DB30>

generator object,结果是一个生成器对象。因为生成器表达式在每次迭代时才会逐个产出元素,所以这里的结果并不是已经创建好的元组。列表推导才会一次性产生新列表所有元素。

通过迭代把生成器表达式结果输出:

for tshirt in tshirts:
 print(tshirt)
('black', 'S')
('white', 'S')
('black', 'M')
('white', 'M')
('black', 'L')
('white', 'L')

生成器表达式可以提升程序性能,比如要计算两个各有1000个元素的列表的笛卡尔积,生成器表达式可以帮忙省掉运行for循环的开销,即一个包含100万个元素的列表。

yield作用和return差不多,后面会讲到。

Tips

本小节内容是我看《流畅的Python》第一遍时记录的知识点:

  1. Python标准库用C实现了丰富的序列类型。
  2. 列表推导,就是指a = [x for x in something]这种写法。
  3. 生成器表达式用于生成列表外的其他类型的序列,它跟列表推导的区别仅仅在于方括号换成圆括号,如b = tuple(x for x in something)
  4. array.array('I', x for x in something) ,array构造方法的第一个参数指定了数组中数字的存储方式。
  5. for tshirt in [c, s for c in colors for s in sizes],列表推导会一次性生成这个列表,存储在内存中,占用资源。for tshirt in ('%s %s' for c in colors for s in sizes),生成器表达式只在循环时逐个产出元素,避免额外的内存占用,省掉了运行for循环的开销。

小结

本文首先介绍了序列的概念,然后演示了Python常规骚操作——列表推导,最后引出了生成器表达式这个看似复杂实则简单的语法。列表是可变的,它有个不可变的孪生兄弟,元组。

参考资料:

以上就是python 列表推导和生成器表达式的使用的详细内容,更多关于python 列表推导和生成器表达式的资料请关注三水点靠木其它相关文章!

Python 相关文章推荐
利用Python的Flask框架来构建一个简单的数字商品支付解决方案
Mar 31 Python
用实例详解Python中的Django框架中prefetch_related()函数对数据库查询的优化
Apr 01 Python
Python根据文件名批量转移图片的方法
Oct 21 Python
python同步两个文件夹下的内容
Aug 29 Python
python基于event实现线程间通信控制
Jan 13 Python
Python virtualenv虚拟环境实现过程解析
Apr 18 Python
详解Django自定义图片和文件上传路径(upload_to)的2种方式
Dec 01 Python
python实现KNN近邻算法
Dec 30 Python
python 进制转换 int、bin、oct、hex的原理
Jan 13 Python
Python 带星号(* 或 **)的函数参数详解
Feb 23 Python
Python读取文件夹下的所有文件实例代码
Apr 02 Python
Django利用AJAX技术实现博文实时搜索
May 06 Python
matplotlib部件之矩形选区(RectangleSelector)的实现
Feb 01 #Python
深入理解Python变量的数据类型和存储
Feb 01 #Python
selenium3.0+python之环境搭建的方法步骤
Feb 01 #Python
Pytorch 图像变换函数集合小结
Feb 01 #Python
Scrapy+Selenium自动获取cookie爬取网易云音乐个人喜爱歌单
Feb 01 #Python
python中xlrd模块的使用详解
Feb 01 #Python
python中使用np.delete()的实例方法
Feb 01 #Python
You might like
php date与gmdate的获取日期的区别
2010/02/08 PHP
PHP浮点数的一个常见问题
2016/03/10 PHP
php基于CodeIgniter实现图片上传、剪切功能
2016/05/14 PHP
php 后端实现JWT认证方法示例
2018/09/04 PHP
Jquery中获取iframe的代码
2011/01/11 Javascript
用js判断页面刷新或关闭的方法(onbeforeunload与onunload事件)
2012/06/22 Javascript
js中eval()函数和trim()去掉字符串左右空格应用
2013/02/02 Javascript
使用JavaScript实现旋转的彩圈特效
2015/06/23 Javascript
jQuery+html5+css3实现圆角无刷新表单带输入验证功能代码
2015/08/21 Javascript
AngularJS在IE下取数据总是缓存问题的解决方法
2016/08/05 Javascript
js实现多行文本框统计剩余字数功能
2017/03/28 Javascript
微信小程序表单验证错误提示效果
2017/05/19 Javascript
浅谈箭头函数写法在ReactJs中的使用
2017/08/22 Javascript
JS中使用textPath实现线条上的文字
2017/12/25 Javascript
node.js中路由,中间件,ge请求和post请求的参数详解
2017/12/26 Javascript
AngularJS实时获取并显示密码的方法
2018/02/06 Javascript
JS中offset和匀速动画详解
2018/02/06 Javascript
p5.js入门教程之键盘交互
2018/03/19 Javascript
浅谈React 服务器端渲染的使用
2018/05/08 Javascript
解决淘宝cnpm 安装后cnpm不是内部或外部命令的问题
2018/05/17 Javascript
Python搭建APNS苹果推送通知推送服务的相关模块使用指南
2016/06/02 Python
深入理解Python对Json的解析
2017/02/14 Python
使用python在本地电脑上快速处理数据
2017/06/22 Python
​如何愉快地迁移到 Python 3
2019/04/28 Python
python 实现图片上传接口开发 并生成可以访问的图片url
2019/12/18 Python
python中的split()函数和os.path.split()函数使用详解
2019/12/21 Python
scrapy爬虫:scrapy.FormRequest中formdata参数详解
2020/04/30 Python
使用CSS3 制作一个material-design 风格登录界面实例
2016/12/12 HTML / CSS
德国箱包网上商店:koffer24.de
2016/07/27 全球购物
单位实习证明怎么写
2014/01/17 职场文书
个性车贴标语
2014/06/24 职场文书
小学校园广播稿(3篇)
2014/09/19 职场文书
外贸英文求职信范文
2015/03/19 职场文书
2015年技术员工作总结
2015/04/10 职场文书
SpringCloud的JPA连接PostgreSql的教程
2021/06/26 Java/Android
Java 超详细讲解hashCode方法
2022/04/07 Java/Android