生成器
(一)什么是生成器
- Python中的生成器是一种特殊的迭代器,可以在需要时生成数据,而不必提前从内存中生成并存储整个数据集。
- 通过生成器,可以逐个生成序列中的元素,而无需一次性生成整个序列。
- 生成器在处理大数据集时,具有节省内存、提高效率的特点。
- 生成器是一种特特殊迭代器。
- 迭代器不一定是生成器
- 生成器一定是迭代器
"""生成器"""
#生成器:是一种特殊的迭代器
#迭代器不一定是生成器
#生成器一定是迭代器
(二)生成器创建方式
(1)列表推导式
- 使用列表推导式时,可以将列表推导式的方括号改为圆括号,即可创建一个生成器。
#1.列表生成式生成列表
list=[ i for i in range(5)]
print(list)#[0, 1, 2, 3, 4]
#2.将列表改成元组
#看起来是一个元组,其实是一个生成器对象
tuple=(i for i in range(5))
print(tuple)#<generator object <genexpr> at 0x000001B4913044A0>
#用next()打印出生成器的每一个元素
print(next(tuple))
print(next(tuple))
print(next(tuple))
print(next(tuple))
print(next(tuple))
# 0
# 1
# 2
# 3
# 4
#生成器本身就是一个迭代器,可以用for循环遍历生成器对象
tuple=(i for i in range(5))
for i in tuple:
print(i)
# 0
# 1
# 2
# 3
# 4
(2)yield关键字
- yield关键字介绍
- 使用yield关键字定义一个生成器函数时,生成器函数中的yield语句会暂停函数执行并返回一个值,下一次调用该函数时会继续执行并返回下一个值。
"""yield关键字"""
# my_generator()是一个生成器函数,通过yield关键字来逐个生成值
# 调用函数时,会得到一个生成器对象
# 可以用next()逐个的返回生成器中的值。
def my_generator():
yield 1
yield 2
yield 3
my_generator=my_generator()
print(next(my_generator))
print(next(my_generator))
print(next(my_generator))
# 1
# 2
# 3
- send方法 只能传一个位置参数,如果下传多个,可以考虑可变数据类型: 列表/字典/元组/集合。
# # send方法 只能传一个位置参数,如果下传多个,可以考虑可变数据类型: 列表/字典/元组/集合
# def eater():
# print('开始吃饭 ovo ')
# while True:
# yield '开始喽' # 第一次 next 发现有一个 yield ,卡住了
# kwargs = yield # 第二次 next 发现有一个 yield ,卡住了
# print(f'得到的食物是 :>>>> {kwargs}, 开始吃饭喽 :>>>> {kwargs}')
#
# my_eat = eater()
# print(next(my_eat), type(next(my_eat)))#开始喽 <class 'NoneType'>
# print(next(my_eat))# 得到的食物是 :>>>> None, 开始吃饭喽 :>>>> None 开始喽
# print(next(my_eat))#None
# print(next(my_eat))#得到的食物是 :>>>> None, 开始吃饭喽 :>>>> None 开始喽
# send方法传入一个参数
# def eater():
# print('开始吃饭 ovo ')
# while True:
# yield '开始喽' # 第一次 next 发现有一个 yield ,卡住了
# kwargs = yield # 第二次 next 发现有一个 yield ,卡住了
# print(f'得到的食物是 :>>>> {kwargs}, 开始吃饭喽 :>>>> {kwargs}')
#
# my_eat = eater()
# print(next(my_eat), type(next(my_eat)))#开始吃饭 ovo 开始喽 <class 'NoneType'>
# print(my_eat.send('麻辣香锅!'))#得到的食物是 :>>>> 麻辣香锅!, 开始吃饭喽 :>>>> 麻辣香锅! 开始喽
# print(next(my_eat))#None
# print(next(my_eat))#得到的食物是 :>>>> None, 开始吃饭喽 :>>>> None 开始喽
# print(next(my_eat))#None
# # send方法传入多个参数
# def eater():
# print('开始吃饭 ovo ')
# while True:
# yield '开始喽' # 第一次 next 发现有一个 yield ,卡住了
# kwargs = yield # 第二次 next 发现有一个 yield ,卡住了
# print(f'得到的食物是 :>>>> {kwargs["food"]}, {kwargs["name"]}开始吃饭喽 :>>>> {kwargs["food"]}')
#
# my_eat=eater()
# print(next(my_eat))#开始吃饭 ovo 开始喽 <class 'NoneType'>
# print(next(my_eat))#None
# print(my_eat.send({'food':'酸菜鱼','name':'syh'}))#得到的食物是 :>>>> 酸菜鱼, syh开始吃饭喽 :>>>> 酸菜鱼 开始喽
# print(next(my_eat))#none
- 定义生成器并使用装饰器
# # 定义生成器 并使用装饰器
# def outer(func):# func -----eater生成器函数
# def inner(*args,**kwargs):
# my_eat=func(*args,**kwargs)# my_eat 是得到生成器对象
# next(my_eat)#开始吃饭ovo
# return my_eat
# return inner
# @outer
# def eater(*args,**kwargs):
# print('开始吃饭 ovo ')
# while True:
# kwargs = yield # 第二次 next 发现有一个 yield ,卡住了
# print(f'得到的食物是 :>>>> {kwargs}, {kwargs} 开始吃饭喽 :>>>> {kwargs}')
#
# res=eater()
# print(res)
# res.send('酸菜鱼')#得到的食物是 :>>>> 酸菜鱼, 酸菜鱼 开始吃饭喽 :>>>> 酸菜鱼
生成器实现for循环
# 生成器实现for循环
def my_range(start,end,step=2):
if start>end:
print(f"开始值不能大于结束值")
while start<end:
yield start
start+=step
myrange=my_range(start=0,end=10,step=2)
print(next(myrange))
print(next(myrange))
print(next(myrange))
print(next(myrange))
print(next(myrange))
# 0
# 2
# 4
# 6
# 8
标签:生成器,yield,next,print,my,eat
From: https://www.cnblogs.com/suyihang/p/17901828.html