什么是生成器:
- 生成器是 Python 中的一个对象(按照某种规律,来生成元素的对象),生成器不是列表,保存了产生元素的算法,同时会记录游标的位置(现在拿到第几个元素了),为了下次继续拿数据,而不是从头开始拿数据。可以通过一直调用 next() 方法获取值,这个对象不保存数据,每次调用会返回一个值,即做到了列表的好处,又不占用空间。
- 在 Python 中,这种一边循环一边计算的机制,称为生成器:generator,生成器是在需要用到数据的时候再提供,相比列表生成器一次性生成多个数据,不占内存
- 生成器是一个特殊的程序,可以被用作控制循环的迭代行为,Python 中生成器是迭代器的一种,使用 yield 返回值函数,每次调用 yield 会暂停,而可以使用 next() 函数和 send() 函数恢复生成器。
生成器的创建方式:
- 生成器表达式
- a = (expression for iterm in iterable)
- 生成器函数
- 在一个普通函数中使用 yield 关键字
- yield 类似于 return 函数,可以将 yield 后面的对象返回,并且记住这个返回的位置,下次通过 next 迭代时,代码从 yield 的下一条语句开始执行。
- 在一个普通函数中使用 yield 关键字
- 生成器函数内部,不允许使用 return 语句返回任何值,因为生成器函数已经默认返回一个生成器了,但是你可以只写一个 return,后面不带任何值
生成器的取值方式:
- 通过 next() 函数取值
- 通过 send(value) 函数取值
- 通过 next 和 send 函数取值时,当时取完了,会报 StopIteration 停止迭代错误
- 第一次 send 前如果没有使用 next 函数进入生成器,则第一个 send 只能传入参数 None,send 类似于 next 可以进入生成器中去执行代码,但是 send 需要传入参数,且将传入的参数赋值给代码中的 yield 前的变量
- 通过 for 循环取值
- 因为生成器本身就是一个特殊的迭代器
实例如下,定义生成器及通过 next 和 for 循环执行取值:
# 第一种创建生成器的方式 b = (i for i in range(5)) print(b) # <generator object <genexpr> at 0x0000000000F5B360> generator 是一个生成器 # print(b.__next__()) # 通过私有方法 __next__() 进入生成器中取值 # print(next(b)) # 通过内置函数 next() 进入生成器中取值,依次取值,取完后再取就报迭代结束错误 for x in b: # 通过 for 循环取值,生成器本身是一个迭代器,是一个可迭代对象 print(x)
# 第二种创建生成器的方式 通过yield创建 def func(): print("hello1") yield 1 # yield 类似return,具有返回值作用 print("hello2") yield 2 f = func() print(next(f)) # 第一次next执行到yield1 结果:hello1和1 print(next(f)) # 第二次next从yield1开始执行,执行到yield2停止 结果:hello2和2 # 结果如下: hello1 1 hello2 2
# 斐波那契数列 0 1 1 2 3 5 8 def fibo(max): n, before, after = 0, 0, 1 while n < max: print(after) before, after = after, before+after n += 1 fibo(3) # 通过生成器计算斐波那契数列 def fibo(max): n, before, after = 0, 0, 1 while n < max: yield after before, after = after, before+after n += 1 f = fibo(3) for i in f: print(i) # 结果如下 1 1 2
实例如下,定义生成器及通过 send 执行取值:
# send()函数 def func(): print("hello1") count1 = yield 1 print(count1) print("hello2") count2 = yield 2 print(count2) yield 3 f = func() # print(f.next()) # || 上下两行代码相等 print(f.send(None)) # 第一次send()前如果没有next(),只能传入一个None,send类似与next可以进入生成器中去执行代码,但是send需要传入参数,且传给代码中yeild前的变量count1 print("--------------") print(f.send("world1")) print("--------------") print(f.send("world2")) # 结果如下 hello1 1 -------------- world1 hello2 2 -------------- world2 3
标签:Python,after,生成器,yield,next,send,print From: https://www.cnblogs.com/ZhengYing0813/p/16847219.html