生成器简介
生成器是一个函数,它返回一个对象(迭代器),可迭代
生成器函数与普通函数的区别
- 生成器函数包含一个或多个yield语句
- 调用时,它返回一个对象(迭代器),但不会立即开始执行
- 自动实现iter()和next()方法,可通过next()遍历
- 遇到yield,将暂停执行函数
- 局部变量在连续调用中可传递
- 当函数终止,StopIteration会在进一步调用时自动引发
```python
带循环的生成器
def rev_str(my_str): length = len(my_str) for i in range(length - 1, -1, -1):# 遇到yield,暂停该函数
yield my_str[i]
# 下一次遍历时从此处开始执行print
print(f"i = {i}")
if name == “main“: for char in rev_str(“hello”): print(char)
“”” o i = 4 l i = 3 l i = 2 e i = 1 h i = 0 “””
<a name="AiOZs"></a>
### 生成器表达式
另一个生成器(generator)的最简单的例子,由于列表生成式受内存空间限制,把列表推导式的 [] 换成 (),变成一个生成器,边计算边循环。
```python
print((x for x in range(10))) #<generator object <genexpr> at 0x0000022293E4DCC8>
生成器的使用
与迭代器相比,生成器实现比较清晰和简单
# 迭代器--实现幂次为2的序列
class PowTwo:
def __init__(self, max=0):
self.n = 0
self.max = max
def __iter__(self):
return self
def __next__(self):
if self.n > self.max:
raise StopIteration
result = 2 ** self.n
self.n += 1
return result
# 生成器--实现幂次为2的序列
def PowTwoGen(max=0):
n = 0
while n <= max:
yield 2 ** n
n += 1
生成器的优点
- 节约内存:生成器一次只返回一项
Case
生成器实现斐波那契数列
函数每次执行到yield时,都会中断,并且返回b的值,下次执行则从中断之后的代码开始执行。def fibo(max_num):
a, b, n = 0, 1, 0
while n < max_num:
yield b
a, b = b, a + b
n += 1
return 'None'
生成器实现杨辉三角
# 生成器实现杨辉三角方法一
def triangles():
p = [1]
while True:
yield p
p = [1] + [p[i] + p[i+1] for i in range(len(p)-1)] + [1]
n = 0
for t in triangles():
print(t)
n += 1
if n == 10:
break
# 生成器实现杨辉三角方法二
# 假设上一个n 为[1, 1]
# 则s = [1, 1, 0]
# 通过式子可得 n = [1, 2, 1]
def triangles():
p = [1] # 初始化为[1],杨辉三角的每一行为一个list
while True:
yield p
s = p[:] # 将p赋值给s,通过s计算下一行
s.append(0) # 将list添加0, 作为最后一个元素,长度增加1
p = [s[i-1] +s[i] for i in range(len(s))] # 通过s来计算出n
n = 0
for t in triangles():
print(t)
n += 1
if n == 10:
break