第三章--生成器generator

列表生成式 

需求:将列表 lis = [0,1,2,3,4,5,6,7,8,9]每个值➕1

这样情况就可以利用列表生成式

lis = [i+1  for i in range(10)]

lis = [1,2,3,4,5,6,7,8,9,10]

生成器  generator

像上面这种情况,如果列表内容很多,我们只需要取一部分,不想一次性全部输出数据该怎么办呢?

这个时候我们就可以利用生成器,生成器的语法和列表生成式很像。

创建生成器语法1:(类似列表生成式的方式)

      lis = (i for i in range(10))

      当执行lis的时候其实就是启动了这个算法,如果下一次次取得计算结果就用

      next(lis)

      生成器保存的是算法,每次调用next(lis)的时候就计算出lis 一直到最后一个元素的时候还next(lis)就会报错

所以我们创建了generator以后 一般不用next()语法,这样会报错,直接用for循环 这样就可以循环输出结果,不用担心报错。

调用生成器:(for循环)

lis = (i for i in range(10))

调用: for item in lis

     print(item)

用for循环的时候调用生成器就直接打用,不需要next()调用,并且不会报错

调用生成器2:(while循环)

lis = (i for i in range(10))

while True:

  print(next(lis))

一般就用for循环,也不会报错。

创建生成器方式2:(函数)yield

def  range2(n):

  count = 0

  while count <n:

    print(count)

    count += 1

    yield count 

new_range = range2(10)  # 这个时候调用函数相当于创建生成器

next(new_range)  # 调用生成器

next(new_range)  # 再次调用生成器

#补充一点,在next后面只能接受一个变量名,也就是必须给调用函数一个变量名

yield和return

return 返回并终止函数

yield 返回,并冻结当前的执行过程(比如循环就会冻结在这里不继续循环)

next() 唤醒冻结的函数执行过程,函数就会继续执行,直到碰到yield 。

函数生成器的创建和调用,相当于就是在函数循环过程中加了 yield,当调用函数的时候就是创建了生成器, 后面next()就是调用生成器,也就等于把函数执行的结果一段一段返回。

函数中遇到yield ,执行函数就得到生成器,return在生成器中代表了中止,就会直接报错。

send

def  range2(n):

  count = 0

  while count <n:

    print(count)

    count += 1

    yield count 

new_range = range2(10)  # 这个时候调用函数相当于创建生成器

next(new_range)  # 调用生成器

new_range.send('stop')

send的作用:和next的作用相同

作用1、唤醒冻结的程序并继续执行

作用2、发送一个信息到生成器内部,也就是yield里

作用:在循环过程中,边循环边计算,这样可以节省内存。假设执行创建一个列表,如果这个列表非常大,一次性创建这个列表需占用很大内存,有的时候我们可能不需要这么多数据,那就可以利用生成器,你需要一次就取一次,没取一次就计算一次,没收到下一个指令时不会计算下面的。

函数调用法,当这个函数的执行内容非常复杂,我又不需要一次性执行完,那我就可以利用生成器,

函数一次性拿到结果,生成器可以把函数执行中每一个过程都可以返回到外面。

原文地址:https://www.cnblogs.com/aaaajayheng1990/p/8823296.html