【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=',')