Python 生成器(generator)解析

引入,玩过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) 
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章