Python札记42_生成器generator

先看个例子:

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()方法,查看运行过程:

Python札记42_生成器generator_第1张图片
image.png

  • 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
Python札记42_生成器generator_第2张图片
image.png

yield

  • 调用函数不会立即执行函数体内的语句
  • 作为生成器的函数,有了yield,会挂起。
  • 有了yield就是生成器,就有__next__()方法
Python札记42_生成器generator_第3张图片
image.png

利用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
Python札记42_生成器generator_第4张图片
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

你可能感兴趣的:(Python札记42_生成器generator)