【python】基础之生成器

  • 1.什么是生成器?
    • 是Python中一种特殊的迭代器,它是一个能按需生成值的轻量级对象。与一次性创建所有元素的数据结构(如列表或元组)不同,生成器在每次迭代时只生成下一个值,从而节省内存并支持无限序列或其他大量数据流的操作。
# iter中简单是4行代码,可以代替MyRangeIterator一样的功能
class MyRange:
    def __init__(self,stop_value):
        self.stop_value = stop_value

    def __iter__(self):
        # return MyRangeIterator(self.stop_value)
        # 执行过程:
        # 1.调用当前方法,不执行(内部创建迭代器对象)
        # 2.调用__next__方法,才执行
        # 3.执行yield语句,暂时离开
        # 4.再次调用__next__方法,继续执行
        # 5.重读3-4步骤,直到结束
        number = 0
        while number < self.stop_value:
            yield number
            number += 1
"""
class MyRangeIterator:
    def __init__(self,end_value):
        self.__end_value = end_value
        self.__number = 0

    def __next__(self):
        if self.__number == self.__end_value:
            raise StopIteration
        temp = self.__number
        self.__number += 1
        return temp
"""

my01 = MyRange(10)
iterator = my01.__iter__()
while True:
    try:
        item = iterator.__next__()
        print(item)
    except StopIteration:
        break

  • 使用了yield的函数被称为生成器(generator),yield是一个关键字,用于定义生成器函数,跟普通的函数不同的是,生成器是一个返回迭代器的函数,当在生成器中使用yield语句时,函数的执行将会暂停,并且将yield后面的表达式作为当前迭代的值返回,然后每次调用生成器的next()方法或者for循环进行迭代时,函数会从上次暂停的地方继续执行,直到再次遇到yield语句。这样生成器函数可以逐步产生值,而不需要一次性计算并返回所有结果。

  • 2.创建生成器

    • 2.1:生成器表达式
gen1 = (i * 2 for i in range(10))
print(gen1)    #<generator object <genexpr> at 0x00000203CCB59F20>
  • 2.2:yield关键字
def my_range(stop_value):
    number = 0
    while number < stop_value:
        yield number
        number += 1

my01 = my_range(10)
for item in my01:
    print(item)
  • 3.访问生成器
gen1 = (i * 2 for i in range(3))
print(gen1)    #<generator object <genexpr> at 0x00000203CCB59F20>
# 方式1,for循环
# for i in gen1:
#     print(i)

# 方式2,next方法
# print(next(gen1))
# print(next(gen1))

# 方式3,__next__()方法
# print(gen1.__next__())
# print(gen1.__next__())

# 方式4,send方法
# send方法是python中生成器的一个方法,用于在生成器内部发送一个值并且继续执行到下一个yield语句
# 当调用send(value)时,这个value将会作为上一个yield的表达式的返回值。

def simple_generator():
    value = None
    while True:
        received_value = yield value
        if received_value is not None:
            value = received_value * 2

# 创建一个生成器对象
gen = simple_generator()
# 启动生成器,获取第一个yield的返回值
first_value = next(gen)
print(first_value)   # None

# # 使用send方法方式一个值
response = gen.send(5)  # 这里的5 将会被赋值给上一个yield表达式,并且将5 * 2 赋值给value
print(response)   # 10
# # 继续方式另一个值
response = gen.send(10)
print(response)

  • 4.生成器使用示例1
# 定义一个生成器函数,模拟银行账户存款和取款过程

def bank_account():
    balance = 0   # 初始化金额0
    while True:
        print(f'当前余额:{balance},')
        amount = (yield balance)  # yield语句暂停并且返回当前余额
        # 使用send方法时,amount将被接受外部传入的值
        if amount is not None:
            if amount > 0:  # 如果发送的金额大于0,则为存款操作,余额相应增加
                balance += amount
                print(f'存入了{amount}元')
            elif amount < 0:
                if balance + amount >= 0: # 表示余额充足,可以取款
                    balance += amount
                    print(f'取出{abs(amount)}元')
                else:
                    print('余额不足,无法取出')
            else:
                print("没有操作金额")

# 创建生成器实例
account = bank_account()
next(account)  # 初始化生成器,执行到第一个yield语句
# 使用send方法进行存取款操作
account.send(1000)
"""
当前余额:0,
存入了1000元
当前余额:1000,
"""
account.send(-600)
"""
当前余额:1000,
取出600元
当前余额:400,
"""
account.send(-500)
"""
余额不足,无法取出
当前余额:400,
"""
  • 5.生成器使用示例2
#  1.函数打印斐波那契数列
# def fib(n):
#     l = []
#     a,b = 0,1
#     for _ in range(n):
#         l.append(a)
#         a,b = b,a+b
#     return l
# print(fib(5))

#  2.使用生成器打印斐波那契数列
def fib():
    a,b = 0,1
    while True:
        yield a
        a,b = b,a+b
gen = fib()
for _ in range(10):
    print(next(gen),end=',')
posted @ 2024-08-27 23:04  Tony_xiao  阅读(73)  评论(0编辑  收藏  举报