生成器

生成器

  • 生成器一定是迭代器,迭代器不一定是生成器
    • 可以在需要时生成数据,通过生成器,可以逐个生成序列中的元素,而无需一次性生成整个序列
  • 生成器也能用next()方法,因为生成器是一种特殊的迭代器

【一】生成器的两种创建方式

(1)列表生成式

  • 列表
num_list = [i for i in range(10)]
print(num_list)

(2)元组生成式

  • 查看元组生成式里面的数据:用list类型强转成列表
num_tuple = (i ** 2 for i in range(10))
print(num_tuple, type(num_tuple)) # <generator object <genexpr> at 0x000002CCAA794350> <class 'generator'>
print(list(num_tuple)) # [0, 1, 4, 9, 16, 25, 36, 49, 64, 81]

【二】yield关键字

(1)yield关键字介绍

  • 使用yield关键字定义一个生成器函数时,生成器函数中的yield语句会暂停函数执行并返回一个值,下一次调用时会继续执行并返回下一个值
def my_generator():
yield 1
yield 2
yield 3
my_iter = my_generator()
print(next(my_iter))
print(next(my_iter))
print(next(my_iter))

(2)yield关键字使用

  • 向yield传值的前提是,必须卡在使用这个值的前面的yield上面
def eat():
print('开始吃饭')
while True:
food = yield
print(f'得到的食物是 :>>>{food},开始吃饭:>>> {food}')
my_eat=eat()
print(next(my_eat))
print(my_eat.send('宫保鸡丁'))
# 开始吃饭
# None
# 得到的食物是 :>>>宫保鸡丁,开始吃饭:>>> 宫保鸡丁
# None
  • send方法只能传一个位置参数,不能传两个,如果想传多个,可以考虑可变数据类型:字典/列表/元组/集合
def wrapper(func): # eater 生成器函数
def inner(*args, **kwargs):
my_eat = func(*args, **kwargs) # my_eat得到的是生成器对象
# print(my_eat) # <generator object eater at 0x000001DA9FB668F0>
next(my_eat) # 开始吃饭 ovo
return my_eat
return inner
@wrapper # eater = wrapper(eater)
def eater():
print('开始吃饭 ovo ')
while True:
kwargs = yield # 第二次 next 发现有一个 yield ,卡住了
print(f'得到的食物是 :>>>> {kwargs["food"]}, {kwargs["name"]} 开始吃饭喽 :>>>> {kwargs["food"]}')
res = eater()
res.send({'food': '茄子肉丁', 'name': 'hope'})
res.send({'food': '拔丝红薯', 'name': 'dream'})

(3)生成器实现for循环

def my_range_one(start, end, step=1):
if end < start:
print(f'开始值不能大于结束值')
while start < end:
yield start
start += step
for i in my_range_one(start=1, end=10, step=1):
print(i)
posted @   ssrheart  阅读(37)  评论(0编辑  收藏  举报
相关博文:
阅读排行:
· 无需6万激活码!GitHub神秘组织3小时极速复刻Manus,手把手教你使用OpenManus搭建本
· Manus爆火,是硬核还是营销?
· 终于写完轮子一部分:tcp代理 了,记录一下
· 别再用vector<bool>了!Google高级工程师:这可能是STL最大的设计失误
· 单元测试从入门到精通
点击右上角即可分享
微信分享提示