Python札记42_生成器generator

浏览: 1213

先看个例子:

my_tuple = (x**x for x in range(4))
my_tuple

<generator object <genexpr> at 0x00000210B3244CF0> # generator是生成器的意思

yield

yielf定义

在Python中定义生成器必须使用关键字yield。它作为一个关键字,是生成器的标志。

  • 有了yield关键字的函数说明是个生成器对象,这个生成器对象也是迭代器。
  • 语句在调用的时候返回相应的值
  • 含有yield关键字语句的函数称之为生成器。生成器是一种用普通函数语法定义的迭代器。
  • 普通函数(包含yield)--->生成器--->迭代器
def func():
yield 0 # 必须有关键字
yield 1
yield 2

>>func
<function __main__.func()>
>>type(func)
function

>>g = func() # 调用func函数并且赋值给g
>>g
<generator object func at 0x00000210B32447C8>

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

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

image.png

yield

  • 调用函数不会立即执行函数体内的语句
  • 作为生成器的函数,有了yield,会挂起。
  • 有了yield就是生成器,就有__next__()方法

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

n是否满足while条件a(前)b(前)a(后)b(后)
0是0111
1是1112
2是1223
3是2335
4是3558
5是58813
6是8131321
7是13212134
8是21343455
9是34555589

推荐 0
本文由 皮大大 创作,采用 知识共享署名-相同方式共享 3.0 中国大陆许可协议 进行许可。
转载、引用前需联系作者,并署名作者且注明文章出处。
本站文章版权归原作者及原出处所有 。内容为作者个人观点, 并不代表本站赞同其观点和对其真实性负责。本站是一个个人学习交流的平台,并不用于任何商业目的,如果有任何问题,请及时联系我们,我们将根据著作权人的要求,立即更正或者删除有关内容。本站拥有对此声明的最终解释权。

0 个评论

要回复文章请先登录注册