一直对Python的yield
关键字有点迷糊,今天整理下相关的知识。
迭代的概念
Python是一门极其灵活的语言,其很多数据里都包含了其他类型的元素。而我们在实际使用的时候,经常需要逐个地取出元素。逐个获取元素的过程,就是迭代。
Python的 list
,tuple
,string
等顺序类型,还包括 dict
,set
等也都是。就是如果我们可以从一个对象中,逐个地获取元素,那么这个对象是「可迭代的」。
至于迭代器则是抽象的一个数据流,是只允许迭代一次的对象。
1 | for i in range(10): |
生成器和yield关键字
生成器函数是一种特殊的函数,而生成器则是特殊的迭代器。
1 | def func(): |
最重要的差异是二者返回的类型是不一样的,生成器函数返回一个迭代器。
yield
yield
关键字仅用户定义生成器函数。与普通函数不同的是,生成器函数是惰性计算的,只有在返回的生成器调用成员方法时,相应函数中的代码才会被执行。
1 | def square(): |
由前面可知,square_gen
表示一个迭代器对象,for 循环会调用迭代器对象的 next()
函数,将生成器中的下一个值赋值给 x , 然后再继续循环,直到终止。
yield的好处
节省时间空间上的开销。Python 之所以要提供这样的解决方案,是因为在很多时候,我们只是需要逐个顺序访问容器内的元素。大多数时候,我们不需要一口气获取容器内所有的元素。
实战一下
生成斐波那契数列1
2
3
4
5
6
7
8def gen_fib(n_max):
n,a,b = 0,0,1
while n < n_max:
yield b
a , b = b , a+b
n += 1
fib = [x for x in gen_fib(10)]
fib # [1, 1, 2, 3, 5, 8, 13, 21, 34, 55]
参考
感恩 始终 这位大佬,跟着走一遍打了一遍!