生成器
- 生成器一定是迭代器,迭代器不一定是生成器
- 可以在需要时生成数据,通过生成器,可以逐个生成序列中的元素,而无需一次性生成整个序列
- 生成器也能用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)) |
| print(list(num_tuple)) |
【二】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('宫保鸡丁')) |
| |
| |
| |
| |
- send方法只能传一个位置参数,不能传两个,如果想传多个,可以考虑可变数据类型:字典/列表/元组/集合
| def wrapper(func): |
| def inner(*args, **kwargs): |
| my_eat = func(*args, **kwargs) |
| |
| next(my_eat) |
| return my_eat |
| |
| return inner |
| |
| @wrapper |
| def eater(): |
| print('开始吃饭 ovo ') |
| while True: |
| kwargs = 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) |
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· 无需6万激活码!GitHub神秘组织3小时极速复刻Manus,手把手教你使用OpenManus搭建本
· Manus爆火,是硬核还是营销?
· 终于写完轮子一部分:tcp代理 了,记录一下
· 别再用vector<bool>了!Google高级工程师:这可能是STL最大的设计失误
· 单元测试从入门到精通