python 生成器
来源:互联网 发布:java连接池原理 编辑:程序博客网 时间:2024/05/20 19:47
1.生成器
生成器的概念要比迭代器稍显复杂,因为生成器是能够返回一个迭代器的函数,其最大的作用是将输入对象返回为一个迭代器。Python中使用了迭代的概念,是因为当需要循环遍历一个较大的对象时,传统的内存载入方式会消耗大量的内存,不如需要时读取一个元素的方式更为经济快捷。
生成器是一次生成一个值的特殊类型函数(特殊的迭代器)。可以将其视为可恢复函数。调用该函数将返回一个可用于生成连续 x 值的生成器Generator。
有两点要先明确:
任意生成器都是迭代器(反之,不成立)
任意生成器,都是一个可以延迟创建值的工厂(可控性)
生成器的创建
将列表生成式中[]改成()
通过列表生成式,可以直接创建一个列表。但是,受到内存限制,列表容量肯定是有限的。而且,创建一个包含百万元素的列表,不仅是占用很大的内存空间,如:我们只需要访问前面的几个元素,后面大部分元素所占的空间都是浪费的。
因此,没有必要创建完整的列表(节省大量内存空间)。在Python中,我们可以采用生成器:边循环,边计算的机制—>generator
>>> L = [x*x for x in range(10)]>>> L[0, 1, 4, 9, 16, 25, 36, 49, 64, 81]>>> g = (x*x for x in range(10))>>> g<generator object <genexpr> at 0x0000028F8B774200>
我们该怎么打印元素呢?
刚刚提到生成器是特殊的迭代器,可以通过next()内置函数来获得generator的下一个返回值:
>>> g = (x*x for x in range(10))>>> g<generator object <genexpr> at 0x0000028F8B774200>>>> next(g)0>>> next(g)1>>> next(g)4>>> next(g)9>>> next(g)16>>> next(g)25>>> next(g)36>>> next(g)49>>> next(g)64>>> next(g)81>>> next(g)Traceback (most recent call last): File "<input>", line 1, in <module>StopIteration
generator是保存的算法,每次调用next()内置函数,才能计算出下一个元素,但一直这样,是不是有种崩溃的赶脚!
那种变态的方式肯定不能用的,正因为generator也是可迭代对象,我们可以使用for循环。
>>> g = (x*x for x in range(10))>>> for i in g:... print(i)... 0149162536496481
这里使用for循环,没有出现异常情况,是和迭代器一样的,都是因为for循环的内部机制。
2.函数—关键字yield创建生成器
简单的说就是在函数的执行过程中,yield语句会把你需要的值返回给调用生成器的地方,然后退出函数,下一次调用生成器函数的时候又从上次中断的地方开始执行,而生成器内的所有变量参数都会被保存下来供下一次使用。
著名的斐波那契数列用列表生成式写不出来,但用函数很简单:
>>> def fib(max): n, a, b = 0, 0, 1 while n < max: print(b) a, b = b, a + b n = n + 1 return 'done'>>> fib(6)112358'done'
斐波那契数列的推算规则非常类似generator,也就是说上面的函数和generator无限接近了,只需要把print(b)改成yield b就行:
>>> def fib(max): n, a, b = 0, 0, 1 while n < max: yield b a, b = b, a + b n = n + 1 return 'done'>>> f = fib(6)>>> f<generator object fib at 0x0000022C041D4360>
懵逼状态:函数和generator执行流程不一样。函数时顺序执行,遇到return语句或者最后一行函数语句就结束,而generator在每次执行next()时,遇到yield语句返回,再次执行时会从上次返回的yield语句处继续执行。
举个简单的生成器例子:
>>> def odd(): print('step 1') yield 1 print('step 2') yield(3) print('step 3') yield(5)>>> o = odd()>>> next(o)step 11>>> next(o)step 23>>> next(o)step 35>>> next(o)Traceback (most recent call last): File "<input>", line 1, in <module>StopIteration
小结:
生成器对象就是一种特殊的迭代器,满足迭代器协议,可以调用next()内置函数;对生成器for 循环时,调用iter()方法返回了生成器对象,然后再不断next()迭代,而iter()和next()都是在yield内部实现的。
生成器创建方式:常见两种(列表生成式、函数关键字)
- Python 生成器
- Python生成器
- python生成器
- python 生成器
- python生成器
- python生成器
- python生成器
- python生成器
- python 生成器
- python生成器
- python 生成器
- python生成器
- python 生成器
- Python--生成器
- python 生成器
- Python 生成器
- python-生成器
- Python生成器
- 最小二乘法拟合圆公式推导及其实现
- [c++实验报告]第四次实验报告:循环结构设计
- 在powershell上使用python
- 数据库参数对mysql性能的影响
- hadoop1.2.1伪分布搭建
- python 生成器
- Spring Boot Shiro 权限管理
- Shell——变量详解及注意点
- Postgresql允许远程访问配置修改
- !important,对于属性优先级提升程度的探究。
- iOS for循环创建button,button的宽度根据上面的文字来自适应.
- python爬虫实例项目大全
- Core Dump
- C# 线程池ThreadPool的用法,多线程编程