先看个例子:
my_tuple = (x**x for x in range(4))
my_tuple
at 0x00000210B3244CF0> # generator是生成器的意思
yield
yielf定义
在Python中定义生成器必须使用关键字
yield
。它作为一个关键字,是生成器的标志。
- 有了yield关键字的函数说明是个生成器对象,这个生成器对象也是迭代器。
- 语句在调用的时候返回相应的值
- 含有
yield
关键字语句的函数称之为生成器。生成器是一种用普通函数语法定义的迭代器。 - 普通函数(包含
yield
)--->生成器--->迭代器
def func():
yield 0 # 必须有关键字
yield 1
yield 2
>>func
>>type(func)
function
>>g = func() # 调用func函数并且赋值给g
>>g
>>type(g)
generator # 注意比较g和func类型的不同,g是生成器对象
查看生成器g的具体方法:
>>dir(g)
['__class__',
'__del__',
'__delattr__',
'__dir__',
'__doc__',
'__eq__',
'__format__',
'__ge__',
'__getattribute__',
'__gt__',
'__hash__',
'__init__',
'__init_subclass__',
'__iter__', # 说明对象是可迭代的
'__le__',
'__lt__',
'__name__',
'__ne__',
'__new__',
'__next__', # 说明对象是可迭代器对象
'__qualname__',
'__reduce__',
'__reduce_ex__',
'__repr__',
'__setattr__',
'__sizeof__',
'__str__',
'__subclasshook__',
'close',
'gi_code',
'gi_frame',
'gi_running',
'gi_yieldfrom',
'send',
'throw']
yield执行
通过执行上面的g生成器对象的next()方法,查看运行过程:
-
g = func():
引用一个生成器对象 -
g.__next__():
生成器开始执行,遇到第一个yield
语句返回其值0,并且暂停执行(称之为挂起) -
g.__next__():
从上次的位置开始,继续执行,返回值1,挂起 -
g.__next__():
从上次的位置开始,继续执行,返回值2,挂起 -
g.__next__():
从上次的位置开始,继续执行,但是后面没有可执行的对象,故报错。
yield vs return
函数返回值由一个return,那么yield和return有什么区别呢?
return
- 一般函数中,return后面的语句不会执行
- 调用函数立刻执行函数体内的语句
def return_func(n):
print("hell python")
while n > 0:
print("before return")
return n # return后面的语句不会执行
n -= 1
print("after return")
>>res = return_func(3)
hell python
before return
yield
- 调用函数不会立即执行函数体内的语句
- 作为生成器的函数,有了
yield
,会挂起。 - 有了
yield
就是生成器,就有__next__()
方法
利用yield生成斐波那契数列
def fibs(max):
n, a, b = 0, 0, 1
while n < max:
yield b
a, b = b, a + b # 如果满足while条件,将b值赋给a,它们俩的和赋值给b
n += 1 # 用来控制次数
if __name__ == "__main__":
f = fibs(10)
for i in f:
print(i)
# 结果
1
1
2
3
5
8
13
21
34
55
n | 是否满足while条件 | a(前) | b(前) | a(后) | b(后) |
---|---|---|---|---|---|
0 | 是 | 0 | 1 | 1 | 1 |
1 | 是 | 1 | 1 | 1 | 2 |
2 | 是 | 1 | 2 | 2 | 3 |
3 | 是 | 2 | 3 | 3 | 5 |
4 | 是 | 3 | 5 | 5 | 8 |
5 | 是 | 5 | 8 | 8 | 13 |
6 | 是 | 8 | 13 | 13 | 21 |
7 | 是 | 13 | 21 | 21 | 34 |
8 | 是 | 21 | 34 | 34 | 55 |
9 | 是 | 34 | 55 | 55 | 89 |