- 201 直观理解 yield
- 202 yield与生成器
- 203 yield 和 send函数
- 204 yield 使用案例之嵌套 list 的完全展开
- 205 yield 使用案例之列表分组
- 206 可迭代协议之 *iter* 方法使用案例
- 207 迭代器相关方法之 next 函数使用
- 208 定制一个递减迭代器案例
- 209 Python 生成枚举对象的方法
- 210 列表和迭代器区别
- 211 节省内存的案例
- 212 拼接迭代器
- 213 累积迭代器
- 214 漏斗迭代器
- 215 drop 迭代器
- 216 take 迭代器
- 217 克隆迭代器
- 218 复制元素
- 219 笛卡尔积
- 220 加强版zip
- 221 自定义装饰器之call_print
- 222 装饰器本质
- 223 wraps 装饰器
- 224 统计程序异常出现次数的迭代器
- 225 实现一个按照 2*i+1 自增的迭代器
201 直观理解 yield
要想通俗理解 yield
,可结合普通函数的返回值关键字 return
,yield便是一种特殊的return
.
说是特殊的 return
,是因为执行遇到 yield
时,立即返回,这是与 return
的相似之处。
不同之处在于:下次进入函数时直接到 yield
的下一个语句,而 return
后再进入函数,还是从函数体的第一行代码开始执行。
带 yield
的函数是生成器,通常与 next函数
结合用。下次进入函数,意思是使用 next函数
进入到函数体内。
举个例子说明 yield
的基本用法。
下面是被熟知的普通函数 f
, f()
就会立即执行函数:
In [1]: def f():
...: print('enter f...')
...: return 'hello'
In [2]: ret = f()
enter g...
In [3]: ret
Out[3]: 'hello'
但是,注意观察下面新定义的函数 f
,因为带有 yield
,所以是生成器函数 f
def f():
print('enter f...')
yield 4
print('i am next sentence of yield')
执行 f
,并未打印任何信息:
g = f()
只得到一个生成器对象 g
再执行 next(g)
时,输出下面信息:
In [18]: next(g)
enter f...
Out[18]: 4
再执行 next(g)
时,输出下面信息:
In [23]: next(g)
i am next sentence of yield
---------------------------------------------------------------------------
StopIteration Traceback (most recent call last)
<ipython-input-23-e734f8aca5ac> in <module>
----> 1 next(g)
StopIteration:
输出信息 i am next sentence of yield
, 表明它直接进入yield的下一句。
同时,抛出一个异常:StopIteration
,意思是已经迭代结束。
202 yield与生成器
函数带有 yield
,就是一个生成器,英文 generator
,它的重要优点:节省内存。
可能有些读者不理解怎么做到节省内存的?下面看一个例子。
首先定义一个函数 myrange
:
def myrange(stop):
start = 0
while start < stop:
yield start
start += 1
使用生成器 myrange
:
for i in myrange(10):
print(i)
返回结果:
0
1
2
3
4
5
6
7
8
9
整个过程空间复杂度都是 O(1),这得益于 yield
关键字,遇到就返回且再进入执行下一句的机制。
以上完整过程,动画演示如下: