Python中的生成器建立的两种方法

引述

通过列表生成式,我们可以直接创建一个列表。但是,受到内存限制,列表容量肯定是有限
的。而且,创建一个包含 100 万个元素的列表,不仅占用很大的存储空间,如果我们仅仅
需要访问前面几个元素,那后面绝大多数元素占用的空间都白白浪费了。
所以,如果列表元素可以按照某种算法推算出来,那我们是否可以在循环的过程中不断推
算出后续的元素呢?这样就不必创建完整的 list,从而节省大量的空间。在 Python 中,
这种一边循环一边计算的机制,称为生成器(Generator)。

1.列表生成器改写

要创建一个 generator,有很多种方法。第一种方法很简单,只要把一个列表生成式的[ ] 改成
() ,就创建了一个 generator

例:判断2~num之间有多少个质数

def isPrime(num):
    for i in range(2, num):
        if num % i == 0:
            return  False
    else:
        return True
 ##列表生成式:
 primeLi =  [i for i in range(1,1000) if isPrime(i)]
 print(primeLi)
 ##生成器:通过列表生成式改写. 一边循环, 一边计算。
primeLi =  (i for i in range(2,1000) if isPrime(i))
##如果要一个一个打印出来,可以通过 generator 的 next() 方法
print(next(primeLi))

这里写图片描述

##将生成器执行完
from collections import  Iterable
for i in primeLi:
    print(i)
 ##判断是否可以for循环
print(isinstance(primeLi,Iterable)) 

2.yield方法

当函数中包含yield关键字,返回值是一个生成器, 如果要执行函数内容.需要调用next方法, 
或者for循环.
运行过程: 当执行next方法时, 遇到yield程序停止, 直到执行下一次next方法时,
从上一次停止的yield处继续执行,遇到yield停止运行.
return: 遇到return函数执行结束;

例:实现斐波那契数列

斐波纳契数列以如下被以递推的方法定义:F(1)=1,F(2)=1,F(n)=F(n-1)+F(n-2)(n>=2,
n∈N*)
 1, 1, 2, 3, 5, 8, 13, 21, 34, 55, 89, 144, 233,377,610,987,1597,2584,
 4181,6765,10946,17711,28657,46368........
def fib(num):
    #num为生成的数量
    a = 0
    b = 1
    count = 0
    while count < num:
        yield  b
        a, b = b, a+b
        count += 1
res = fib(100)
print(next(res))

这里写图片描述

生成器: 如果函数中有yield, 那么这个函数的返回值就是一个生成器。

生成器fib()执行的过程分析:
  执行语句 f = fab(100) 时,并不会马上执行 fib() 函数的代码块,而是首先返回一个 iterable 对象(即生成器)!
  在 for 循环语句执行时或者next(),才会执行 fib() 函数的代码块。
  执行到语句 yield b 时,fib() 函数会返回一个迭代值,直到下次迭代前,
  程序会回到 yield b 的下一条语句继续执行,然后再次回到 for 循环,如此迭代直到结束。
  看起来就好像一个函数在正常执行的过程中被 yield 中断了数次,每次中断都会通过 yield 返回当前的迭代值。
  由此可以看出,生成器通过关键字 yield 不断的将迭代器返回到内存进行处理,而不会一次性的将对象全部放入内存,
  从而节省内存空间。

通过生成器创建的迷你机器人

 生成器可以使用的方法:
   - next(g)
   - g.send(''), 给生成器传递值;
    给yield所在位置发送一个数据, 直到遇到下一个yield停止.
def chat_robot():
    res = ''
    while True:
        receive = yield res
        if 'age' in receive:
            res = '你猜'
        elif 'hello' in receive:
            res = '你好鸭'
        elif 'name' in receive:
            res = 'My name is villa'
        elif 'sex' in receive:
            res = "I'm a boy?"
        else :
            res = "I don't know what you say"

def main():
    Robot = chat_robot()
    next(Robot)
    while True:
        send_data = input("Messi>>:")
        if send_data == 'q' or send_data == 'bye':
            print("不聊了,我也撤了......")
            break
        print(Robot.send(send_data))           ##send_data给Robot传值
main()

运行结果:
这里写图片描述

猜你喜欢

转载自blog.csdn.net/weixin_41179709/article/details/81806933