python | 探寻python生成器

简介: python | 探寻python生成器

image.png


面试官: 听说你熟悉python,那么你能简单阐述一下python的装饰器、生成器以及迭代器么?

我: emm, 我不清楚,我只是了解过python最基本的代码。

上述是弟弟前段时间去面试运维开发,遇到的问题,emmm,运维是一个很杂的职业,在小公司,总结一句话就是宽而浅,痛定思痛,决定来了解一下python特性,于是乎,就有了这篇文章。


这边文章,我们将介绍python生成器,使用环境为: Python 3.6.8


image.png

如果你还没有了解过迭代器,建议查看迭代器的文章:《python | 你知道for...in是底层原理是什么样的么?探寻python迭代器》



什么是python生成器


上一篇文章我们介绍了迭代器,而生成器是一种特殊的迭代器,它内部也有__iter__方法和__next__方法,在终止生成器的时候,还是会抛StopIteration异常以此来退出循环,只不过相比于迭代器,生成器还有特性会保存“中间值”,下次运行的时候,还会借助这个“中间值”来操作。

生成器的关键字是yield,我们下面来写一个最简单的生成器。

image.png

粗看代码,可能会觉着这个是个啥啊,为啥不直接用range来生成,偏偏要用yield,哎,不急,我们接着往下看为什么需要生成器,或者说,生成器解决了什么问题。



为什么需要python生成器


在说明这个问题之前,我们先来写一个需求,输出 0——10000000 以内的数据,而后运行查看导出内存运行截图。


调用python程序内存信息辅助说明


这里可以借助pythonmemory_profiler模块来检测程序内存的占用情况。

安装memory_profiler库:

image.png

使用方法很简单,在需要检测的函数或者是代码前添加@profile装饰器即可,例如:

image.png


生成.dat文件

image.png

导出图示,可以使用

image.png


python案例代码


以下2个程序,都是输出0—9999999之间的数据,不同的是,第一个程序是使用range而后给appendlist中,第二个则是使用迭代器来生成该数据。

main.py程序

image.png


main_2.py程序image.png


运行程序

代码也有了,就可以按照上述来运行一下程序,并且导出内存信息

image.png


运行后内存信息查看

main.py 运行内存图

image.png



main_2.py 运行内存图


image.png


如上2张对比图,当我们将数据叠加进列表,再输出的时候,占用内存接近400M,而使用迭代器来计算下一个值内存仅使用16M。


通过上述案例,我们应该知道为什么要使用生成器了吧。



python生成器原理


由于生成器表达式yield语句涉及到了python解释权内部机制,所以很难查看其源码,很难获取其原理,不过我们可以利用yield的暂停机制,来探寻一下生成器。


可以编写如下代码:

image.png


运行后效果如下

image.png


通过上述实例,再结合下面这段生成器的运行过程,会加深对生成器的感触。


python遇到yield语句时,会记录当前函数的运行状态,并且暂停执行,将结果抛出。会持续等待下一次调用__next__方法,该方法调用后,会恢复函数的运行,直至下一个yield语句或者函数结束,执行到最后没有yield函数可执行的时候,会抛StopIteration来标志生成器的结束。



生成器表达式


python中,生成器除了写在函数中,使用yield返回之外,还可以直接使用生成器表达式,额。。。可能很抽象,但是你看下面这段代码,你就明白了。


image.png


其中,代码(i for i in [1,2,3,4,5])就等同于printNums函数,其类型都是生成器,我们可以使用type打印出来看下。

改下代码,输出结果如下:

image.png


好了,生成器表达式其实不复杂,暂时就讲到这里。



总结


该篇文章是介绍python生成器,所谓的生成器其实也是一个特殊的迭代器,其底层依然有__iter____next__方法,不仅如此,它还可以将函数“暂停”,当遇到_next__后,又从上一次暂停的地方开始执行,既然是一个特殊的迭代器,所以还是会引发StopIteration异常。而后介绍了为什么需要生成器,距了一个例子,分别打印0——n个数,一个使用生成器 还有一个 使用list,当然list会更加耗费内存,最后介绍了生成器原理 以及 生成器表达式。



相关文章
|
2月前
|
大数据 数据处理 开发者
Python中的迭代器和生成器:不仅仅是语法糖####
本文探讨了Python中迭代器和生成器的深层价值,它们不仅简化代码、提升性能,还促进了函数式编程风格。通过具体示例,揭示了这些工具在处理大数据、惰性求值及资源管理等方面的优势。 ####
|
3月前
|
存储 索引 Python
|
2月前
|
JavaScript 前端开发 算法
python中的列表生成式和生成器
欢迎来到瑞雨溪的博客,这里是一位热爱JavaScript和Vue的大一学生的天地。通过自学前端技术2年半,现正向全栈开发迈进。如果你从我的文章中受益,欢迎关注,我将持续更新高质量内容,你的支持是我前进的动力!🎉🎉🎉
30 0
|
3月前
|
Python
Python生成器、装饰器、异常
【10月更文挑战第15天】
|
3月前
|
传感器 大数据 数据处理
深入理解Python中的生成器:用法及应用场景
【10月更文挑战第7天】深入理解Python中的生成器:用法及应用场景
95 1
|
3月前
|
存储 数据处理 Python
深入解析Python中的生成器:效率与性能的双重提升
生成器不仅是Python中的一个高级特性,它们是构建高效、内存友好型应用程序的基石。本文将深入探讨生成器的内部机制,揭示它们如何通过惰性计算和迭代器协议提高数据处理的效率。
|
2月前
|
存储 程序员 数据处理
深入理解Python中的生成器与迭代器###
本文将探讨Python中生成器与迭代器的核心概念,通过对比分析二者的异同,结合具体代码示例,揭示它们在提高程序效率、优化内存使用方面的独特优势。生成器作为迭代器的一种特殊形式,其惰性求值的特性使其在处理大数据流时表现尤为出色。掌握生成器与迭代器的灵活运用,对于提升Python编程技能及解决复杂问题具有重要意义。 ###
|
3月前
|
存储 大数据 数据处理
Python 中的列表推导式与生成器:特性、用途与区别
Python 中的列表推导式与生成器:特性、用途与区别
37 2
|
3月前
|
存储 大数据 Python
Python 中的列表推导式和生成器
Python 中的列表推导式和生成器
27 1
|
4月前
|
机器学习/深度学习 设计模式 大数据
30天拿下Python之迭代器和生成器
30天拿下Python之迭代器和生成器
23 3