生成器

发布时间 2023-12-13 12:20:24作者: 蓝幻ﹺ

生成器

  • Python中的生成器是一种特殊的迭代器,可以在需要时生成数据,而不必提前从内存中生成并存储整个数据集。
  • 通过生成器,可以逐个生成序列中的元素,而无需一次性生成整个序列。
  • 生成器在处理大数据集时,具有节省内存、提高效率的特点。
  • 迭代器不一定是生成器,生成器一定是迭代器。

列表生成式

list1 = [x for x in range(5)]
print(list1)
# [0, 1, 2, 3, 4]

元组生成式

生成器对象可以强转成列表

tuple1 = (x**2 for x in range(5))
print(tuple1)
print(list(tuple1))
# <generator object <genexpr> at 0x000002208D89F580>
# [0, 1, 4, 9, 16]

print(tuple1.__next__())  #0
print(tuple1.__next__())  #1

yield关键字

​ 使用yield关键字定义一个生成器函数时,生成器函数中的yield语句会暂停函数执行并返回一个值,下一次调用该函数时会继续执行并返回下一个值。

def eater():
    print('开始吃饭 ovo ')
    while True:
        yield '开始'
        food = yield
        print(f'得到的食物是 :>>>> {food}, 开始吃饭喽 :>>>> {food}')


a=eater()
print(next(a))  #开始吃饭 ovo   开始
print(next(a))   #None
# 向yield传值前提必须卡在使用这个值前面的yield上面
print(a.send('鸡腿'))   #得到的食物是 :>>>> 鸡腿, 开始吃饭喽 :>>>> 鸡腿   开始
print(next(a))    #None
print(next(a))      #得到的食物是 :>>>> None, 开始吃饭喽 :>>>> None   开始
def eater():
    print('开始吃饭 ovo ')
    while True:
        yield '开始'
        dict1 = yield
        print(f'得到的食物是 :>>>> {dict1["food"]}, {dict1["name"]}:>>>>开始吃饭喽  ')


a=eater()
print(next(a))  #开始吃饭 ovo   开始
print(next(a))   #None
# send 只能传一个值,但可以是字典
print(a.send({'food':'鸡腿','name':'tom'}))  #得到的食物是 :>>>> 鸡腿, tom:>>>>开始吃饭喽   开始
使用装饰器
def init(func):
    def wrapper(*args, **kwargs):
        res = func(*args, **kwargs)
        next(res)
        return res
    return wrapper

@init
def eater():
    print('开始吃饭 ovo ')
    while True:
        food = yield
        print(f'得到的食物是 :>>>> {food}, 开始吃饭喽 :>>>> {food}')


res = eater()
res.send('鸡腿')
res.send('鸭腿')

# 开始吃饭 ovo 
# 得到的食物是 :>>>> 鸡腿, 开始吃饭喽 :>>>> 鸡腿
# 得到的食物是 :>>>> 鸭腿, 开始吃饭喽 :>>>> 鸭腿
  • 若函数体包含yield关键字,再调用函数,并不会执行函数体代码,得到的返回值即生成器对象
生成器实现for循环
def my_range(start, end, step=1):
    if end<start:
        print(f'开始值不能大于结束值!')

    while start < end:
        yield start
        start += step


for i in my_range(start=1,end=10,step=2):
    print(i)