前四天我们学了四样装数据的容器:字符串(一句话)、列表(一串东西)、字典(有名字的数据)、集合(去重)。今天不学新东西,把四样全用上,写两个完整程序:词频统计和成绩管理。
为什么专门安排这一天?因为真实工作里没有一个程序是"只用一种容器"写出来的——都是容器 + 循环 + 判断组合出来的。今天练的不只是代码,更是一种干活方式:先自己写,卡住了问 AI,但动手必须自己来。做完今天的练习,你就能挺直腰板说:我独立写出了有真实用途的小程序,而且我知道怎么跟 AI 一起干活。
先把四个容器摆在一起
写综合练习前,把本周的容器放一起对比一遍,脑子里得有这张表:
| 容器 | 写法 | 特点 | 什么时候用 | 今天的例子 |
|---|---|---|---|---|
| 字符串 | "你好" |
一串文字,只能读不能改 | 存文字、处理文字 | 输入的整句话 |
| 列表 | [1, 2, 3] |
有序、能增删改,靠下标找 | 一串同类型的东西 | 拆出来的单词、成绩列表 |
| 字典 | {"a": 1} |
键值对,靠名字找 | 一个东西的多个属性 | 词频结果、一个学生 |
| 集合 | {1, 2, 3} |
自动去重、无序 | 去重、找重复 | 判断单词有没有重复(了解) |
这张表背后有一个核心公式,今天两个程序就是它的最好示范:所有复杂程序 = 容器 + 循环 + 判断。容器装数据,循环过数据,判断处理数据。
今天会用到的方法,先过一遍"代码速查卡":
s = "python is fun"
words = s.split() # 字符串 → 列表:['python', 'is', 'fun']
cart = []
cart.append("牛奶") # 列表加元素
count = {} # 空字典
count["python"] = 1 # 字典加键值对(不存在就是新增)
students = [{"name": "小明", "score": 92}]
print(students[0]["name"]) # 列表套字典取"一格":小明
for key, value in count.items(): # 遍历字典(键+值)
print(key, value)
三个地方别弄混:别把"容器"和"类型"搞混——"123" 是字符串,123 是数字,["123"] 是列表,三个完全不同;词频统计里,字典的键是单词、值是次数,这个方向别反了;先想清楚"数据放哪个容器"再动手写——数据结构想清楚了,代码就完成一半。
程序一:词频统计
需求:输入一句话,统计每个词出现几次。
写程序前先拆步骤,这是职业习惯:
- 输入一句话(字符串)→
input() - 按空格拆成单词列表 →
split() - 遍历每个单词,数次数 → 字典计数(核心逻辑)
- 打印结果 →
items()遍历输出
第 3 步的"字典计数"是这个程序的心脏,逻辑只有两条:单词没出现过,给字典加一个键,次数记 1;单词出现过,次数加 1。
text = input("请输入一句话:")
words = text.split() # 按空格拆成单词列表
result = {} # 空字典:单词 → 次数
for w in words: # 每个单词来一遍
if w in result: # 以前记过这个单词?
result[w] += 1 # 记过:次数加 1
else:
result[w] = 1 # 没记过:第一次出现,记 1
for w, count in result.items():
print(f"{w}: {count} 次")
假设输入 python is fun and python is cool,输出:
请输入一句话:python is fun and python is cool
python: 2 次
is: 2 次
fun: 1 次
and: 1 次
cool: 1 次
这个"字典计数"模式以后到处用,把逻辑讲透:
if w in result:判断的是单词这个键在不在字典里——in判断键,周三刚学过,这里就用上了。- 为什么不能直接
result[w] += 1?因为第一次出现时result[w]还不存在,直接加会报KeyError,所以必须先判断"有没有"。 - 输入里如果有标点(
python,带逗号),split()会把python,当成一个词——这就是进阶题要解决的问题。
再提三个容易翻车的:统计前先 print(words) 看看拆对了没有,拆错了一切都白搭;单词大小写不同会被当成两个词(Python 和 python),进阶题可以顺手用 lower() 统一;忘写 result = {} 会在 result[w] 时报 NameError,空字典必须先建好。
程序二:成绩管理
需求:存 3 个同学的成绩,算出平均分、最高分、最低分。
同样先拆步骤:
- 数据放哪?→ 列表套字典(一个学生一个字典,昨天刚学的表格结构)
- 怎么算?→ 把所有成绩抽成一列(数字列表)
- 算完怎么输出?→
sum / max / min加 f-string
students = [
{"name": "小明", "score": 92},
{"name": "小红", "score": 85},
{"name": "小刚", "score": 78},
]
# 第 2 步:抽出所有成绩(普通写法 + 推导式写法都行)
scores = [stu["score"] for stu in students] # [92, 85, 78]
# 第 3 步:计算并输出
print(f"平均分:{sum(scores) / len(scores)}") # 平均分:85.0
print(f"最高分:{max(scores)}") # 最高分:92
print(f"最低分:{min(scores)}") # 最低分:78
# 顺手把每个同学的成绩也打印出来(遍历表格)
for stu in students:
print(f"{stu['name']}:{stu['score']} 分")
输出:
平均分:85.0
最高分:92
最低分:78
小明:92 分
小红:85 分
小刚:78 分
几个"为什么"说清楚:数据用列表套字典存,而不是三个独立变量——因为"一个东西的多个属性"就该用字典,"多个同学"就该用列表,这就是周三讲的选择标准;scores 必须是数字列表才能用 sum / max / min,抽列这一步([stu["score"] for stu in students])就是周四讲的"按列抽数据";平均分是 sum / len(总和 ÷ 个数),写成 len / sum 会得到 0 附近的小数,方向别反。
容易出错的地方,集中在"层"和"类型"上:students[0] 是字典,students[0]["score"] 才是成绩,少一层 ["score"] 会算错或报错;抽列时键名写错(stu["Score"])会报 KeyError——键名和字典里的必须一字不差;想算平均分但抽出的是字符串(比如数据里存了 "92")会报 TypeError——数据存的时候就用数字。
卡住了怎么办:AI 协作五步法
今天允许用 AI,但要用得聪明。原则一句话:独立完成,卡住再问 AI。照着这五步走:
| 步骤 | 做什么 | 举例 |
|---|---|---|
| 1. 先自己写 | 能写多少写多少,哪怕只有空壳 | text = input(...)、result = {} |
| 2. 说出卡在哪 | 把"想做什么 + 卡在哪"发给 AI | "词频统计里,怎么判断单词第一次出现" |
| 3. 看思路别抄代码 | 让 AI 先讲思路,自己动手写 | "先别给代码,讲思路" |
| 4. 跑不通就贴报错 | 把完整报错信息发给 AI | 贴 KeyError: 'python' 整段报错 |
| 5. 跑通了再改造 | 跑通基础版,再让 AI 帮加功能 | "加上去掉标点符号" |
第 1 步说的"空壳",长这样——求助 AI 时,自己先写到这个程度再求助:
text = input("请输入一句话:")
words = text.split()
result = {}
for w in words:
# 卡在这里:不知道怎么数次数
pass # pass 表示"先占个位置"
for w, count in result.items():
print(f"{w}: {count} 次")
三条规矩记牢:别一上来就让 AI 写完整代码——先把需求和自己的半成品发过去,AI 给的答案更贴合你的思路;报错信息要完整复制,别只发"报错了"三个字,AI 看不到你的屏幕;让 AI 干活后一定要自己敲一遍代码,光复制粘贴学不会编程。AI 写的代码必须自己读懂,看不懂就让 AI 加注释或"用普通 for 循环改写",抄完看不懂 = 白练。
随堂练习
练习一(必做):词频统计
独立写出词频统计程序(程序一的完整代码),跑通后换一句更长的英文句子再测一遍,确认每个词的次数都对。
提示:跑不通先 print(words) 看拆分结果,再检查"判断 + 加 1 / 记 1"两条分支。
练习二(必做):成绩管理
独立写出成绩管理程序(程序二的完整代码),然后自己加第 4 个同学,重跑验证平均分、最高分、最低分都对。
提示:加同学用 append;分数用数字不要用字符串,否则 sum 报错。
进阶题(可选):词频统计升级——去掉标点
给词频统计升级:把 .、,、! 等标点去掉再统计(输入 Hello, world! Hello python. 应该统计出 hello: 2 次 而不是 hello,: 1 次)。
提示:用 replace 把标点替换成空字符串,注意单词大小写要统一(lower());卡住就问 AI,这是今天的进阶挑战。
参考解法(先自己试 20 分钟,再对照):
text = input("请输入一句话:")
# 第一步:去掉标点符号(把每个标点替换成空字符串)
for p in ".,!?,。!?":
text = text.replace(p, "")
# 第二步:统一成小写,避免 Python 和 python 被当成两个词
text = text.lower()
# 第三步:后面和基础版完全一样
words = text.split()
result = {}
for w in words:
if w in result:
result[w] += 1
else:
result[w] = 1
for w, count in result.items():
print(f"{w}: {count} 次")
假设输入 Hello, world! Hello python.,输出:
请输入一句话:Hello, world! Hello python.
hello: 2 次
world: 1 次
python: 1 次
这个进阶程序把本周的知识全用上了:replace 去标点(周一)、lower 统一大小写(周一)、split 拆词(周一)、for 遍历(周二)、字典计数(周三)——五天的知识一个不落。
写不出来时,让 AI 搭把手
场景:成绩管理程序让 AI 写参考实现
提示词:
我是 Python 初学者,正在学字典和列表。我有 3 个学生的成绩,
想存进一个字典列表,然后算出平均分、最高分、最低分。
请帮我写 Python 代码,数据用列表套字典表示,
用普通 for 循环(不要用列表推导式),代码加注释。
场景:词频统计的去标点升级不会做
提示词:
我的词频统计程序能统计单词次数,但输入 "Hello, world!" 时
会把 "Hello," 和 "world!" 当成单词,带标点。我想先去掉标点
再统计,还要统一大小写。请告诉我怎么做,先讲思路再给代码,
代码加注释,用最简单的写法。
常见报错速查
| 报错信息 | 什么意思 | 怎么办 |
|---|---|---|
KeyError: 'python' |
字典里没有这个键就取值了 | 先用 in 判断,或用 get();词频统计里"第一次出现"要先记 1 |
TypeError: unsupported operand type(s) for +: 'int' and 'str' |
数字和字符串做了加法 | 检查抽出来的成绩是不是数字,input 出来的记得 int() 转换 |
NameError: name 'result' is not defined |
变量没定义就使用 | 检查是不是忘了 result = {} 或拼错了变量名 |
ValueError: could not convert string to float |
把文字转数字失败 | 确认输入的是数字,或数据里没有混入空字符串 |
收个尾
本周到此结束。回头看这四天:字符串(一句话)、列表(一串)、字典(有名字的)、集合(去重),所有复杂程序 = 容器 + 循环 + 判断。词频统计的心脏是"计数模式"——if w in result: result[w] += 1 else: result[w] = 1;成绩管理的套路是——列表套字典存数据 → 抽一列成数字列表 → sum / max / min 计算。能独立完成这两个程序,本周目标就算达成。
下周进入函数、模块与文件:这几天的代码都挤在一起,下周学怎么把一段功能包成函数——写好一次,到处调用。学完你就能写出更长的程序而不乱。周末记得休息好,周六见。
本周测评(周六周测说明)
周六周测说明(周六上机,约 40 分钟):
- 形式:上机操作题,共 4 题,全部在本周所学范围内:
- 字符串切片与加工(
s[0:5]、upper()、replace()等) - 列表增删改查(
append / pop / remove / 下标赋值,遍历打印) - 字典增删改查与遍历(
get取值、items()遍历,判断键是否存在) - 集合去重(
set(列表)去重,找出重复数字) - 考核要点:操作为主、理论为辅。能不能亲手敲出代码比能不能背概念更重要;每题按"跑通 + 结果正确"给分,完成 60% 即通过
- 未通过怎么办:周日照常到教室补测,重点补做错题的部分;补测通过同样算达标
-
复习建议:周六前把第 11~14 章"随堂练习"的题目每题重敲一遍,对着下面的复习清单逐条自查:
-
[ ] 会用切片取字符串 / 列表的一部分
- [ ] 会列表的增删改查(append / pop / remove / 下标改)
- [ ] 会字典的增删改查(get / 新增 / 修改 / pop)
- [ ] 会用
for k, v in 字典.items()遍历字典 - [ ] 会用集合去重
- [ ] 能独立完成词频统计