您的位置:首页 > 编程语言 > Python开发

Python 生成器(generator)解析

2018-03-20 19:12 363 查看
引入,玩过Python的可能都听说过生成器,带yield关键字的函数返回的就是生成器。生成器又有什么作用呢?
   斐波那契数列 
    斐波那契数列是一个递归数列,他的特征就是前两个书相加等于后一个数(除了最前面的两个数)1,1,2,3
    ,5
       看到这里我们可能会想到我们平时最常规的一种实现方式:def creat_fibonacci():
a, b = 1, 0
for x in range(10):
print(b)
a, b = b, a + b这里通过调用creat_fibonacci()方法打印出想要的数列。这里我们可能会想到利用率不是太高,只是遍历,我们怎么可以把他存在一个地方,想用的时候再去调用。
 我们可以将其存入list列表中,在使用的时候在遍历这个列表:def creat_fibonacci():
a, b = 1, 0
lists = []
count = 0
for x in range(10):
lists.append(b)
# print(b)
a, b = b, a + b
count += 1
return lists

list1 = creat_fibonacci()
for x in list1:
print(x)通过这种方式调用时可以更加灵活的使用list列表,但是出现的问题是可能占用的内存空间会比较大,如果生成一万数一百万个呢?可能需要的内存空间就比较大。
从这里我们就开始介绍今天的主角!!!yield
该如何使用呢?这里我先贴一段代码例子def creat_fibonacci():
a, b = 1, 0
for x in range(10):
yield b
a, b = b, a + b

for x in creat_fibonacci():
print(x)这里调用方法时候返回的是一个生成器对象(generator),通过遍历生成器对象,打印数列,这里重点说的是yield的作用,
当我们将返回的生成器对象通过next(gennrator)一次一次遍历的时候,只返回一个数,这里返回的就是 yield 后面跟的属性值,而当你在此执行next方法时,他会再次遍历,再次遍历的是接着上次返回时候的地方开始执行。# 第一种遍历
num = creat_fibonacci()
count = next(num)
print(count)
# 第二种遍历
num2 = num.__next__()
print(num2)这两种方式都能遍历出生成器对象。
总结:
    yield 的作用就是把一个函数变成一个 generator,带有 yield 的函数不再是一个普通函数,Python 解释器会将其视为一个 generator,调用 creat_fibonacci() 不会执行 creat_fibonacci 函数,而是返回一个 iterable 对象!在 for 循环执行时,每次循环都会执行 creat_fibonacci函数内部的代码,执行到 yield b 时,creat_fibonacci函数就返回一个迭代值,下次迭代时,代码从 yield b 的下一条语句继续执行,而函数的本地变量看起来和上次中断执行前是完全一样的,于是函数继续执行,直到再次遇到 yield。

Send 的作用
这里还有一个方法send,send的方法时可以对yield位置赋值:def creat_fibonacci():
count = 0
while count < 5:
test = yield count
print(test)
count += 1

num = creat_fibonacci()
num.send("hhh")send方法的作用就是,在每次执行到yield位置时候,返回yield位置的值,当我们再次调用时,代码中test的值是空的,应为不会再将返回的值记录起来赋值给test,这时候我们可以使用send()方法,给上次返回的地方赋值,这里就是讲“hhh”字符串赋值给text,这里next(num)作用同num.send(None)第一次使用时候需要传入None,因为第一调用没有地方赋值,或者调用一次next
判断是否是生成器
    判断要遍历的对象是否是生成器,可以通过generatorfuncton(),方法判断调用的对象是否是生成器对象,判断是否需要遍历。from inspect import isgeneratorfunction
isgeneratorfunction(generator)
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息