内容正文:
红包模拟与迭代器生成器
计 算 机 原 理
(电工版第五版)
学习目标
理解random模块中uniform()函数的随机数生成逻辑;掌握迭代器的核心概念、iter()与next()方法的调用规则;熟悉生成器的定义方式、yield关键字的作用及惰性执行的运行机制。
能够编写Python程序实现普通红包均分与拼手气红包随机分配的核心算法;可自定义类实现迭代器协议以支持自定义对象的遍历操作;能利用生成器高效处理流式数据,解决大数据量场景下的内存占用问题。
通过红包算法模拟案例培养逻辑推理与随机数应用能力,深入理解Python迭代与生成的底层运行原理;在代码实现中提升抽象思维与代码复用能力,逐步养成模块化设计、规范化编码的专业编程习惯。
1
2
3
知识目标
技能目标
素养目标
目录
实战3 红包模拟
迭代器原理与应用
生成器原理与应用
总结回顾与实战演练
教学引入
思考:拼手气红包的金额是如何计算的?如何用代码实现“每个人都能抢到随机金额,且总额刚好”的效果?
知识讲授
迭代器与生成器
迭代器是访问集合元素的单向工具,只能向前遍历且不可复用;生成器是基于yield关键字的特殊迭代器,支持惰性计算,执行时可暂停并保存状态,下次调用从断点继续,在处理大数据集时能极大节省内存开销,是实现高效遍历的核心机制。
uniform() 随机分配函数
Python中random模块的核心函数,用于生成指定区间 [a, b] 内的随机浮点数,遵循均匀分布原则。它是实现“拼手气红包”金额随机分配的关键工具,能保证红包金额在预设总金额和人数范围内的公平、随机分布,是构建各类随机概率逻辑的基础组件。
迭代器原理与应用
第一部分
知识讲授
迭代器原理与应用
知识讲授
迭代的概念
Python中的迭代指的是按照某种顺序逐个访问容器(如列表、元组、字典等)中的元素的过程。
当对可迭代对象进行迭代(for)操作时,首先会调用内置函数iter()返回一个迭代器(Iterator)
对返回的迭代器调用 next()函数,逐个读取迭代器内容
凡是实现了__iter__ (或者__getitem__)方法的都是可迭代对象(Iterable),可迭代对象都可以被迭代器(Iterator)进行迭代操作。
知识讲授
迭代器原理与应用
知识讲授
迭代器的基本方法
01. 迭代器生成:iter()
功能:从可迭代对象(列表、元组等)中获取迭代器实例,是开启遍历的前提。
语法:iter(iterable),参数为任意支持迭代的数据结构。
02. 逐次取值:next()
功能:每次调用返回迭代器的下一个元素,内部指针自动后移。
语法:next(iterator),每调用一次消耗一个元素,指向下一位。
03. 终止标志:StopIteration
机制:当迭代器耗尽所有元素后,再次调用 next() 会抛出此异常。
作用:这并非错误,而是通知程序“迭代已完成”的正常信号。
▍ 迭代执行的完整生命周期流程
1. 初始化准备
创建可迭代对象,
调用 iter() 转换为迭代器。
→
2. 循环取值
持续调用 next(),
逐个读取并处理元素。
→
3. 触发终止信号
无元素可取时,
抛出 StopIteration 异常。
→
4. 迭代结束
捕获异常,
程序结束遍历过程。
知识讲授
迭代器协议
一个对象需要提供next方法,该方法要么返回迭代对象中的下一项,要么就抛StopIteration异常,迭代终止。
在python中,只要一个对象实现了以下两个方法,那么它就是一个迭代器
_ iter _: 返回一个可迭代对象
_ next _: 返回迭代器的下一项,当没有元素可以返回时抛StopIteration异常,迭代终止。
背诵记忆
序号 核心考点 记忆要点与核心解析
01 迭代器 (Iterator) 本质是一个可以记住遍历位置的对象,用于逐个访问集合元素。记忆口诀:“状态记录员,步步向前走”,不会一次性加载所有数据,节省内存。
02 iter() 初始化函数 将列表、元组等“可迭代对象”转换为迭代器对象,是遍历的第一步。记忆口诀:“iter来点火,开启迭代车”,输入可迭代对象,输出迭代器。
03 next() 取值函数 每调用一次就返回迭代器的下一个元素,无元素时抛出 StopIteration 异常。记忆口诀:“next踩油门,逐个取数据”,每次调用只走一步。
课堂练习
基础例题
01. 基础应用:如何访问列表 [1, 2, 3] 的第一个元素?
场景:给定列表对象,需通过迭代器协议获取其首个元素,写出核心代码实现。
02. 特性理解:迭代器遍历结束后,还能重新遍历吗?
思考:若对已耗尽的迭代器再次调用 next() 会发生什么?如何重新实现遍历?
【例题1 答案】使用 iter() 生成迭代器,再用 next() 取值:it = iter([1,2,3]); print(next(it))
【例题1 解析】iter() 是迭代器的构造入口,用于将列表等可迭代对象转换为迭代器对象;next() 是迭代器的访问入口,每次调用都会返回迭代器的下一个元素,首次调用即获取序列的第一个值。
【例题2 答案与解析】不能。迭代器是“一次性单向”的数据流,遍历结束后内部指针已移至序列末尾,无法回退。若需重新遍历,必须通过 iter() 重新创建一个新的迭代器对象,原迭代器无法复用。
师生互动
综合应用:for循环与迭代器的本质
01 核心问题:列表为何能被for循环遍历?
这是Python中最常见的遍历方式,但背后隐藏着被称为“语法糖”的设计。for循环并非直接操作数据,而是自动调用了Python的迭代器协议。这种机制让遍历变得极其简洁,无需手动管理索引、终止条件或异常处理,同时保证了不同可迭代对象(列表、字典、文件等)接口的统一性。
02 后台自动执行的四步流程
1.获取迭代器:隐式调用 iter(list),将列表转为迭代器对象;
2.取值赋值:循环调用 next(),取出元素并赋值给变量 i;
3.异常触发:无元素时自动抛出 StopIteration 异常;
4.循环结束:for循环捕获异常并终止,无需手动干预。
03 迭代器语法糖的核心价值
•极致简洁:省略了C/Java风格的索引管理,代码可读性大幅提升;
•统一接口:无论是序列还是自定义对象,遵循协议即可被遍历;
•内存友好:按需生成数据,无需一次性加载所有元素到内存;
•易于扩展:自定义类只需实现 __iter__ 和 __next__ 即可支持迭代。
生成器原理与应用
第二部分
知识讲授
生成器原理与应用
知识讲授
生成器与迭代器的关系
生成器是创建迭代器的一种极简方式,是Python为简化迭代器实现而设计的语法糖。它本质上是一个特殊的迭代器对象,无需手动编写完整的类即可实现序列的惰性生成。
知识讲授
什么是生成器?
生成器(generator)也是一种迭代器,在每次迭代时返回一个值,直到抛出 StopIteration异常
知识讲授
生成器函数
生成器有__iter__()和__next__()还有一个yield关键字/命令(类似return),生成器之所以能生成是因为保存了一套算法/逻辑可以持续生成数据,yield返回一个值,但是不会结束函数,会记住当前值的位置。
1、生成器表达式
a = (x ** 2 for x in range(100))
print(type(a))
E:\env\python39\python.exe D:\项目\python\deke\test.py
<class 'generator'>
2、生成器函数
class genRange():
def __init__(self,num):
self.num = num
def __iter__(self):
counter = 0
while counter < self.num:
yield counter
counter += 1
obj1 = genRange(5)
for item in obj1:
print(item)
背诵记忆
序号 名称 核心说明与记忆要点
01 生成器核心定义 生成器是带有yield关键字的特殊函数,本质是一种迭代器,调用时不会立即执行函数体。
记忆口诀:“yield定生成,迭代新类型”
02 执行机制与特性 惰性计算(按需生成数据,极大节省内存),执行到yield时暂停并返回值,同时保存执行现场。
记忆口诀:“惰性计算省内存,暂停保存现场稳”
03 唤醒与调用方式 需通过next()函数唤醒生成器,使其从暂停处继续执行,直至遇到下一个yield或函数结束抛出异常。
记忆口诀:“next来唤醒,步步向前行”
课堂练习
Python 生成器核心例题
01. 生成器函数中执行到 yield 关键字时,会发生什么?
A. 程序直接抛出异常 B. 立即结束函数运行 C. 暂停并返回值 D. 触发无限循环
02. 简述生成器表达式与列表推导式的核心差异?
请从数据生成时机与内存占用两个维度进行说明。
【答案】例题1选 C | 例题2:内存机制与生成时机不同
【解析1】yield 是生成器的“暂停与返回”开关,执行时会保存当前函数的执行状态(包括变量值、指令指针),并将值返回给调用方,下次调用 next() 时从暂停处继续执行,而非终止函数。【解析2】列表推导式 `[x for x in range(1000)]` 是“贪婪加载”,一次性生成所有元素存入内存,数据量大时占用高;生成器 `(x for x in range(1000))` 是“惰性生成”,仅在迭代时计算单个元素,内存占用极低,适合处理大数据集。
课堂练习
随堂检测:随机数与生成器
01. 单选题:random.uniform(1.0, 3.0) 不可能产生的值是?
A. 1.5 B. 2.0 C. 3.0 D. 3.1
02. 单选题:下列关于 Python 生成器的描述,正确的是?
A. 生成器函数使用 return 返回值 B. 生成器只能被迭代一次
C. 生成器占用大量内存空间 D. 生成器不能用于 for 循环遍历
【答案与深度解析】
01. 答案:D。解析:random.uniform(a, b) 用于生成 [a, b] 区间内的随机浮点数,该区间是“左闭右闭”的,即包含 1.0 和 3.0,但绝对不会超出这个区间边界。选项 D 的 3.1 大于上限 3.0,因此不可能被生成。
02. 答案:B。解析:生成器是一种特殊的迭代器,其核心特征是“惰性计算”:A 错误,生成器通过 yield 关键字返回值而非 return;B 正确,生成器是一次性的,迭代结束后无法重置或再次使用;C 错误,生成器边生成边输出数据,不会一次性加载所有内容,因此极省内存;D 错误,生成器对象本身就是可迭代对象,可直接用于 for 循环、next() 等迭代场景。
实战3 红包模拟
第三部分
知识讲授
实战3 红包模拟
知识讲授
实战3 红包模拟
程序运行结果:
“红包模拟”程序逻辑流程图
知识讲授
红包模拟逻辑流程
本程序旨在模拟常见的红包分发机制,支持“普通均分红包”与“拼手气随机红包”两种模式。通过接收用户输入的总金额、红包个数及类型参数,利用条件判断和数学计算实现金额的智能分配,最终输出每位用户的领取明细。
data = input("请输入(金额,个数,类型1/2): ").split(',')
核心函数:input() 获取用户输入,split() 分割参数,eval() 转换数值类型
02. 核心分配逻辑
if type == 1: # 普通红包:严格平均分配
each = total_money / num # 每人金额相等
else: # 拼手气:随机分配,确保每人至少0.01元
普通红包侧重绝对公平,拼手气红包则通过随机数算法实现金额差异化,最终输出明细。
流程总结:这是典型的“顺序+分支”结构应用。程序严格遵循“输入数据→判断类型→计算分配→输出结果”的线性执行流,通过条件判断实现不同业务逻辑的切换,是掌握Python流程控制的经典入门案例。
01. 输入交互层
知识讲授
普通红包生成策略
01 核心策略:平均分配
遵循“总额均分”原则,将红包总金额按人数平均切分。这是最基础、最直接的红包发放方式,适用于福利分发、费用平摊等需要绝对公平的场景。
02 计算逻辑:数学均分
公式:单人金额 = 红包总金额 ÷ 红包个数。计算过程无随机因子,结果固定。例如:总额100元拆分为10个红包,每人必得10元,逻辑清晰易懂。
03 核心特点:绝对公平
结果完全可预期,不存在“手气”差异,每个人抢到的金额完全一致。这种确定性消除了随机红包带来的心理落差,是体现公平性的最佳选择。
04 开发要点:精度控制
需处理浮点数运算的精度丢失问题。建议使用round() 函数对计算结果进行四舍五入,保留两位小数,以符合人民币以“分”为最小单位的货币规范。
a
知识讲授
拼手气红包生成策略
01 核心策略:随机分配机制
区别于普通的等额红包,拼手气红包的核心是“随机金额分配”。系统不预设固定数值,而是通过随机算法让每个领取者获得的金额具有不确定性,既保证总金额正确,又增加了互动的趣味性与随机性。
02 算法底层:剩余兜底原则
采用“前n-1随机 + 第n个兜底”的计算模式。先为前n-1个用户随机生成金额,最后一位用户的金额直接等于总金额减去前面所有已分配金额的总和。此逻辑能绝对保证红包总金额无偏差,避免超发或少发问题。
03 代码实现:循环与累加
利用循环结构遍历前n-1个红包,每次生成随机金额并存入列表,同时实时累加已分配的金额;循环结束后,用总金额减去累加的已分配总额,将结果作为最后一个红包的金额补充进列表,完成所有红包的生成。
04 关键函数:uniform() 随机数
在Python中主要使用 `random.uniform(a, b)` 函数,它能在指定区间 [a, b] 内生成一个随机浮点数。该函数保证了金额在最小单位(如0.01元)和剩余可分配金额之间的均匀分布,是实现随机金额的核心工具。
知识讲授
关键函数:uniform()
01 核心基础
所属模块:Python 标准库random,是生成随机浮点数的核心工具。
核心功能:在指定的数值区间内,随机生成一个浮点类型的数值,打破固定数值的确定性。
02 语法与参数
调用语法:random.uniform(a, b)
参数说明:
a → 区间下限(起始值),b → 区间上限(终止值);
a与b无严格大小限制,函数会自动识别并处理区间。
03 特性与应用
返回值:闭区间[a, b]内的随机浮点数,包含两端边界值。
典型场景:拼手气红包的随机金额分配、模拟游戏中的随机概率、数据采样中的随机比例生成。
⚡ 代码实战演示
import random # 导入随机数模块
# 生成 0.01 到 1.0 之间的随机浮点数
result = random.uniform(0.01, 1.0)
# 输出示例:0.3428910572193547(每次运行结果不同)
💡 提示:该函数是实现“非整数型随机结果”的最佳选择,常用于需要精度的随机场景。
第一空 import
第二空 s.split()
师生互动
完善下列代码
第三空 int
第四空
[round(v/n,2) for _ in range(n)]
第五空 n-1
第六空 .append(t)
第七空 v - t
背诵记忆
序号 核心考点 记忆要点与核心解析
01 普通红包策略 规则为金额严格平均分配,核心计算逻辑是单人金额 = 总金额 ÷ 总人数,是最基础的红包分配模型。
记忆口诀:“总额均分,人人相等”
02 拼手气红包逻辑 采用随机分配模式,前n-1个红包随机生成金额,最后1个红包兜底补足剩余金额,保障总额与总金额一致。
记忆口诀:“前n-1随机,最后来兜底”
03 红包模拟核心函数 uniform()生成随机小数(需导入random模块);split()拆分字符串为列表处理输入;round()用于金额四舍五入保留小数。
记忆口诀:“随机uniform,拆分split,取整round”
课堂练习
基础例题
01. 场景计算:普通红包的平均分配
题目:假设发红包总金额为100元,共有10人参与抢红包,若选择“普通红包”模式,请问理论上每人能抢到多少钱?
02. 代码理解:random.uniform 函数应用
题目:在Python中,执行 random.uniform(0.01, 0.1) 语句,可能生成下列哪个数值?(选项:A. 0.00 B. 0.05 C. 0.11 D. 1.0)
【例题1 答案与解析】
答案:10.0 元。解析:普通红包的核心逻辑是“平均分配”,即总金额除以人数。计算过程为 100 ÷ 10 = 10.0,因此每人获得等额的10元。
【例题2 答案与解析】
答案:选 B。解析:random.uniform(a, b) 用于生成 [a, b] 闭区间内的随机浮点数。0.05 在 0.01 到 0.1 范围内;A小于最小值,C、D均大于最大值,均不符合生成规则。
分组讨论
01
核心议题:拼手气红包算法的防负数改进
在基础的拼手气红包随机算法中,若前n-1个红包的随机金额总和超过了预设总金额,会导致最后一个红包金额为负数,这显然不符合实际需求。请结合随机数生成规则与金额分配逻辑,分组探讨改进方案,要求确保每个红包金额至少为0.01元,且所有红包金额之和严格等于总金额。
知识小结
课后任务
布置作业:
1.绘制本节课完整思维导图(涵盖random模块、列表、循环、红包拆分算法、边界处理)。
2.完成课件配套单选、代码填空练习题。
3.自主优化红包模拟程序,增加对总金额、红包个数非法输入的容错处理,以及对"1个红包""金额与个数不匹配"等边界情况的处理,并提交运行结果。
谢谢观看
THANKS
$