一、什么是生成器?(大白话)
- 列表:一次性把所有数据全部创建好,占内存大
- 生成器:不提前存数据,用到一个算一个,超级省内存
- 核心:一边循环,一边计算,不用一次性生成所有元素
二、生成器怎么创建?(2 种方法)
方法 1:把列表生成式的 [] 改成 ()
- 列表:
[x*x for x in range(10)] - 生成器:
(x*x for x in range(10))
方法 2:函数里加 yield 关键字
只要函数里有 yield,这个函数就变成生成器函数!
三、生成器怎么用?
- 不用
next()手动取(太麻烦还会报错) - 直接用 for 循环遍历(最简单、最常用)
四、核心知识点:yield 的作用
普通函数:从头到尾执行,遇到 return 结束
生成器函数:
- 遇到
yield→ 暂停,返回值 - 下次循环 → 从暂停的地方继续执行
- 就像游戏存档,读档继续玩
五、杨辉三角练习题
第一步:先看代码思路(最重要!)
- 第一行固定是
[1],直接开始 - 每一行的开头和结尾都是 1
- 中间的数字 = 上一行左边数字 + 右边数字
- 用
yield返回每一行,实现生成器
第二步:完整代码
python
运行
def triangles():
# 第一行初始化为 [1]
line = [1]
while True:
# 返回当前行,生成器暂停
yield line
# 计算下一行:开头补0 + 上一行 + 结尾补0
# 比如 [1] → [0,1] + [1,0] → 两两相加
line = [line[i] + line[i-1] for i in range(len(line))]
line.insert(0, 1) # 开头加1
# 测试代码(不用改)
n = 0
results = []
for t in triangles():
results.append(t)
n = n + 1
if n == 10:
break
for t in results:
print(t)
if results == [
[1],
[1, 1],
[1, 2, 1],
[1, 3, 3, 1],
[1, 4, 6, 4, 1],
[1, 5, 10, 10, 5, 1],
[1, 6, 15, 20, 15, 6, 1],
[1, 7, 21, 35, 35, 21, 7, 1],
[1, 8, 28, 56, 70, 56, 28, 8, 1],
[1, 9, 36, 84, 126, 126, 84, 36, 9, 1]
]:
print('测试通过!')
else:
print('测试失败!')
六、超简记忆口诀
- 生成器 = 省内存的列表
- 创建:
()或者 函数 +yield - 执行:遇到
yield暂停,循环继续 - 使用:for 循环直接遍历
- 作用:处理大数据、无限序列不卡机
总结
- 生成器核心就是按需计算,不浪费内存
- 函数里写
yield就是生成器 - 用
for循环遍历生成器,最简单安全 - 杨辉三角核心:首尾是 1,中间 = 上一行相邻两数之和s
分割线小tips
生成器和非生成器输出的结果是一样的,只不过生成器更加节省内存
a, b = b, a + b :同时赋值
分割线return和yield区别
yield 和 return 完全不一样!
return:函数直接结束,再也不回来了yield:函数暂停执行,下次还能从暂停的地方继续跑
分割线理解杨辉三角的计算
杨辉三角
-
line [-1] 表示列表最后一个数字!
-
核心就是:
**当前数字 + 左边数字 = 新数字**
我带你演算一遍(最关键!)
我们假设现在 line = [1]
python
运行
line = [line[i] + line[i-1] for i in range(len(line))]
第一步:len (line) = 1
→ range (1) → 只有 i = 0
第二步:计算 i=0
plaintext
line[0] + line[0-1]
= line[0] + line[-1]
重点来了:
line [-1] 表示列表最后一个数字!
所以:
plaintext
1 + 1 = 2
于是这行执行完:
line = [2]
再举第二个例子:line = [1, 2]
range(2) → i=0, i=1
i=0
line[0] + line[-1]
= 1 + 2 = 3
i=1
line[1] + line[0]
= 2 + 1 = 3
最终得到:
line = [3, 3]
最最最通俗的总结
这行代码的作用只有一句话:
让列表里每个数字 + 它左边的数字,生成新列表
分割线练习题
一、基础选择题(3 题)
1. 下面代码运行结果是?
def fun():
yield 10
yield 20
g = fun()
print(next(g))
A. 20 B. 10 C. 报错 D. 10 20
2. range(1, 1) 会生成几个数字?
A. 1 个 B. 0 个 C. 2 个 D. 无数个
3. 关于 yield 说法正确的是?
A. yield 会直接结束函数
B. yield 遇到就暂停,下次从暂停处继续
C. 函数里有 yield 也还是普通函数
二、代码填空题(2 题,最简单)
4. 补全代码,用生成器依次输出 1,2,3
def num():
yield 1
______ 2
yield 3
5. 补全代码,让循环只执行 1 次
line = [1,1]
for i in range(1, ______):
print("执行一次")
三、简单编程题(2 题,上手写)
6. 写一个生成器函数
要求:
- 函数名:
count() - 依次 yield 输出:
5, 10, 15 - 最后用 for 循环遍历打印所有值
7. 理解小练习
已知:
line = [1, 2, 1]
for i in range(1, len(line)):
print(i)
手动写出:会打印出哪几个数字?
四、思考题(1 题,贴合杨辉三角)
8.
为什么杨辉三角代码里:
new_line = [1]
# 中间算数字
new_line.append(1)
开头先写 1、最后再加 1,有什么作用?
答案
一、 第一题:B 第二题:B 第三题:B
二、 第四题:yield 第五题:len(line)
三、 第六题:
def count():
yield 5
yield 10
yield 15
for i in count():
print(i)
第七题:会打印 两个数字。看 range 范围
range(1, 3)
规则:包含左边,不包含右边
👉 取出的数字是:1、2
第八题:
杨辉三角每行首尾一定是 1;
new_line = [1] 先固定开头的 1;
循环只计算中间相加的数字;
append(1) 补上末尾的 1;
组合起来就是完整正确的一行。