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爬取微博数据生成词云图片实例代码
Aug 31 Python
Python 将pdf转成图片的方法
Apr 23 Python
Python使用pylab库实现绘制直方图功能示例
Jun 01 Python
python基础学习之如何对元组各个元素进行命名详解
Jul 12 Python
Django配置celery(非djcelery)执行异步任务和定时任务
Jul 16 Python
tensorflow学习教程之文本分类详析
Aug 07 Python
Python线程之定位与销毁的实现
Feb 17 Python
python+Django实现防止SQL注入的办法
Oct 31 Python
django框架中ajax的使用及避开CSRF 验证的方式详解
Dec 11 Python
Python终端输出彩色字符方法详解
Feb 11 Python
python常用运维脚本实例小结
Feb 14 Python
基于python实现音乐播放器代码实例
Jul 01 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中定义网站根目录的常用方法
2010/08/08 PHP
php下获取Discuz论坛登录用户名、用户组、用户ID等信息的实现代码
2010/12/29 PHP
用JS提交参数创建form表单在FireFox中遇到的问题
2013/01/16 Javascript
解析ScrollPic在ie8下只滚动一遍,然后变为空白 ie6,ie7,chrome,firefox正常
2013/06/26 Javascript
js转义字符介绍
2013/11/05 Javascript
AngularJS 如何在控制台进行错误调试
2016/06/07 Javascript
Jquery表单验证失败后不提交的解决方法
2016/10/18 Javascript
angularjs点击图片放大实现上传图片预览
2017/02/24 Javascript
微信分享调用jssdk实例
2017/06/08 Javascript
详解webpack3如何正确引用并使用jQuery库
2017/08/26 jQuery
js实现QQ面板拖拽效果(慕课网DOM事件探秘)(全)
2017/09/19 Javascript
JavaScript基于面向对象实现的猜拳游戏
2018/01/03 Javascript
JS获取input[file]的值并显示在页面的实现方法
2018/03/09 Javascript
vue中使用iview自定义验证关键词输入框问题及解决方法
2018/03/26 Javascript
小程序实现多选框功能
2018/10/30 Javascript
layui实现三级联动效果
2019/07/26 Javascript
VSCode 添加自定义注释的方法(附带红色警戒经典注释风格)
2020/08/27 Javascript
[31:33]2014 DOTA2国际邀请赛中国区预选赛 TongFu VS DT 第一场
2014/05/23 DOTA
[48:47]VGJ.S vs NB 2018国际邀请赛小组赛BO2 第一场 8.18
2018/08/19 DOTA
用Python编写一个基于终端的实现翻译的脚本
2015/04/24 Python
python 计算两个日期相差多少个月实例代码
2017/05/24 Python
python UDP(udp)协议发送和接收的实例
2019/07/22 Python
python实现H2O中的随机森林算法介绍及其项目实战
2019/08/29 Python
使用PyTorch将文件夹下的图片分为训练集和验证集实例
2020/01/08 Python
python 解压、复制、删除 文件的实例代码
2020/02/26 Python
Python中操作各种多媒体,视频、音频到图片的代码详解
2020/06/04 Python
python re模块常见用法例举
2021/03/01 Python
Oracle的内存结构(Memory structures)
2015/06/10 面试题
口头翻译求职人自荐信
2013/12/07 职场文书
高中打架检讨书
2014/02/13 职场文书
高考标语大全
2014/06/05 职场文书
餐厅收银员岗位职责
2015/04/07 职场文书
工作时间调整通知
2015/04/24 职场文书
2015年质量管理工作总结范文
2015/05/18 职场文书
python使用openpyxl库读写Excel表格的方法(增删改查操作)
2021/05/02 Python
使用python创建股票的时间序列可视化分析
2022/03/03 Python