Python 标准库练习题(含答案)
1. random——随机抽奖
题目: 有一个参与抽奖的名单,编写程序:
- 随机选出 1 名一等奖得主
- 随机选出 3 名二等奖得主(不能和一等奖重复)
- 打印结果
participants = ["张三", "李四", "王五", "赵六", "孙七", "周八", "吴九", "郑十"]
参考答案:
import random
participants = ["张三", "李四", "王五", "赵六", "孙七", "周八", "吴九", "郑十"]
# 一等奖:随机选 1 名
first_prize = random.choice(participants)
# 二等奖:从剩余名单中选 3 名(不能重复)
remaining = [p for p in participants if p != first_prize]
second_prizes = random.sample(remaining, 3)
print(f"🥇 一等奖:{first_prize}")
print(f"🥈 二等奖:{second_prizes[0]}、{second_prizes[1]}、{second_prizes[2]}")
关键点:
random.choice():从列表随机选 1 个random.sample(列表, k):无放回地随机选 k 个,不会重复
2. random——猜数字游戏
题目: 编写一个猜数字游戏:
- 程序随机生成 1~100 之间的整数
- 玩家不断输入猜测值
- 程序提示”太大了”、”太小了”或”恭喜猜对了!”
- 猜对后打印共猜了几次
参考答案:
import random
secret = random.randint(1, 100)
count = 0
print("我已经想好了一个 1~100 之间的整数,请你来猜!")
while True:
guess = int(input("请输入你的猜测:"))
count += 1
if guess < secret:
print("太小了,再大一点!")
elif guess > secret:
print("太大了,再小一点!")
else:
print(f"恭喜你猜对了!答案就是 {secret},你共猜了 {count} 次。")
break
关键点:
random.randint(1, 100):生成 1 到 100 之间的随机整数(包含两端)while True+break:无限循环直到猜对为止
3. datetime——日期格式转换
题目: 把下面的日期字符串统一转换成 "YYYY年MM月DD日" 的格式,并打印出来:
dates = [
"2024-01-15",
"2023-12-31",
"2025-07-04",
]
参考答案:
from datetime import datetime
dates = [
"2024-01-15",
"2023-12-31",
"2025-07-04",
]
for date_str in dates:
# 先解析成 datetime 对象
dt = datetime.strptime(date_str, "%Y-%m-%d")
# 再格式化成目标格式
formatted = dt.strftime("%Y年%m月%d日")
print(formatted)
# 输出:
# 2024年01月15日
# 2023年12月31日
# 2025年07月04日
关键点:
strptime(字符串, 格式):字符串 → datetime 对象(parse)strftime(格式):datetime 对象 → 字符串(format)
4. datetime——倒计时计算
题目: 编写程序,计算距离某个重要日期还有多少天。例如计算距离 2026 年元旦(2026-01-01)还有多少天,并格式化打印当前日期。
参考答案:
from datetime import date
today = date.today()
new_year = date(2026, 1, 1)
diff = new_year - today
days_left = diff.days
print(f"今天是:{today.strftime('%Y年%m月%d日')}")
if days_left > 0:
print(f"距离 2026 年元旦还有 {days_left} 天!")
elif days_left == 0:
print("今天就是 2026 年元旦!新年快乐!")
else:
print(f"2026 年元旦已经过去 {abs(days_left)} 天了。")
关键点:
date.today():获取今天的日期- 两个
date对象相减,得到timedelta对象,.days取天数 diff.days可能为负(目标日期已过)
5. os / pathlib——文件信息统计
题目: 编写程序,统计当前目录下(不含子目录)所有 .md 文件的数量和文件名,打印出来。使用 pathlib 实现。
参考答案:
from pathlib import Path
current_dir = Path(".") # 当前目录
md_files = [f for f in current_dir.iterdir() if f.suffix == ".md" and f.is_file()]
print(f"当前目录下共有 {len(md_files)} 个 .md 文件:")
for f in sorted(md_files):
print(f" {f.name}")
进阶版(包含子目录,用 rglob 递归查找):
from pathlib import Path
all_md = list(Path(".").rglob("*.md")) # 递归查找所有 .md 文件
print(f"共找到 {len(all_md)} 个 .md 文件:")
for f in sorted(all_md):
print(f" {f}")
关键点:
Path(".").iterdir():遍历当前目录(不含子目录)f.suffix:获取文件扩展名(如.md)Path(".").rglob("*.md"):递归查找所有匹配的文件
6. math——几何计算器
题目: 编写一个函数 shape_info(shape, *args),根据图形类型和参数计算面积和周长:
circle(圆):传入半径rectangle(矩形):传入宽和高triangle(三角形,已知三边 a、b、c):用海伦公式计算面积
参考答案:
import math
def shape_info(shape, *args):
if shape == "circle":
r = args[0]
area = math.pi * r ** 2
perimeter = 2 * math.pi * r
print(f"圆(半径={r}):面积={area:.4f},周长={perimeter:.4f}")
elif shape == "rectangle":
w, h = args[0], args[1]
area = w * h
perimeter = 2 * (w + h)
print(f"矩形({w}×{h}):面积={area:.4f},周长={perimeter:.4f}")
elif shape == "triangle":
a, b, c = args[0], args[1], args[2]
s = (a + b + c) / 2 # 半周长
area = math.sqrt(s * (s-a) * (s-b) * (s-c)) # 海伦公式
perimeter = a + b + c
print(f"三角形({a},{b},{c}):面积={area:.4f},周长={perimeter:.4f}")
else:
print(f"未知图形:{shape}")
shape_info("circle", 5)
shape_info("rectangle", 4, 6)
shape_info("triangle", 3, 4, 5)
输出:
圆(半径=5):面积=78.5398,周长=31.4159
矩形(4×6):面积=24.0000,周长=20.0000
三角形(3,4,5):面积=6.0000,周长=12.0000
关键点: math.sqrt() 求平方根,math.pi 是圆周率常数。
7. json——读写学生成绩
题目: 编写程序完成以下操作:
- 把下面的学生成绩数据保存到
scores.json文件 - 再从文件读取回来
- 计算每位学生的平均分并打印
students = [
{"name": "张三", "scores": {"语文": 88, "数学": 92, "英语": 85}},
{"name": "李四", "scores": {"语文": 75, "数学": 68, "英语": 90}},
{"name": "王五", "scores": {"语文": 95, "数学": 88, "英语": 79}},
]
参考答案:
import json
students = [
{"name": "张三", "scores": {"语文": 88, "数学": 92, "英语": 85}},
{"name": "李四", "scores": {"语文": 75, "数学": 68, "英语": 90}},
{"name": "王五", "scores": {"语文": 95, "数学": 88, "英语": 79}},
]
# 第一步:写入 JSON 文件
with open("scores.json", "w", encoding="utf-8") as f:
json.dump(students, f, ensure_ascii=False, indent=2)
print("成绩已保存到 scores.json")
# 第二步:从文件读取
with open("scores.json", "r", encoding="utf-8") as f:
loaded = json.load(f)
# 第三步:计算平均分并打印
print("n学生成绩报告:")
print("-" * 35)
for student in loaded:
name = student["name"]
scores = student["scores"].values()
avg = sum(scores) / len(scores)
print(f"{name}:各科成绩 {list(student['scores'].values())},平均分 {avg:.1f}")
输出:
成绩已保存到 scores.json
学生成绩报告:
-----------------------------------
张三:各科成绩 [88, 92, 85],平均分 88.3
李四:各科成绩 [75, 68, 90],平均分 77.7
王五:各科成绩 [95, 88, 79],平均分 87.3
关键点:
json.dump(数据, 文件对象):写入文件json.load(文件对象):从文件读取ensure_ascii=False:允许中文,indent=2:美化格式
8. collections.Counter——词频统计
题目: 对下面这段文字进行词频统计(按空格分词),找出出现次数最多的 5 个词,打印词和对应的出现次数。
text = """python is great python is easy to learn python is powerful
programming with python is fun python community is large and supportive"""
参考答案:
from collections import Counter
text = """python is great python is easy to learn python is powerful
programming with python is fun python community is large and supportive"""
words = text.split() # 按空格分词
counter = Counter(words) # 统计每个词的出现次数
print("词频统计(前5名):")
for word, count in counter.most_common(5):
bar = "█" * count # 用方块直观显示频次
print(f" {word:15} {count} 次 {bar}")
输出:
词频统计(前5名):
python 5 次 █████
is 5 次 █████
great 1 次 █
easy 1 次 █
to 1 次 █
关键点:
Counter(列表):统计列表中各元素的出现次数counter.most_common(n):返回出现次数最多的 n 个元素,格式为[(元素, 次数), ...]
9. collections.defaultdict——按类型分组
题目: 把下面的商品列表按照类别分组,用 defaultdict 实现,打印每个类别的商品列表。
products = [
("苹果", "水果"),
("牛奶", "饮品"),
("香蕉", "水果"),
("橙汁", "饮品"),
("薯片", "零食"),
("草莓", "水果"),
("可乐", "饮品"),
("巧克力", "零食"),
]
参考答案:
from collections import defaultdict
products = [
("苹果", "水果"),
("牛奶", "饮品"),
("香蕉", "水果"),
("橙汁", "饮品"),
("薯片", "零食"),
("草莓", "水果"),
("可乐", "饮品"),
("巧克力", "零食"),
]
# defaultdict(list):不存在的键自动初始化为空列表
grouped = defaultdict(list)
for name, category in products:
grouped[category].append(name)
print("商品分类:")
for category, items in grouped.items():
print(f" {category}:{', '.join(items)}")
输出:
商品分类:
水果:苹果, 香蕉, 草莓
饮品:牛奶, 橙汁, 可乐
零食:薯片, 巧克力
关键点: defaultdict(list) 让你直接 grouped[key].append(value) 而不用先检查键是否存在,避免 KeyError。
10. re——数据提取
题目: 从下面的文本中,用正则表达式分别提取:
- 所有日期(格式:YYYY-MM-DD)
- 所有金额(格式:数字 + “元”,如 “1500元”)
- 所有邮箱地址
text = """
会议记录:
日期:2024-03-11,地点:北京
参会人:张三(zhangsan@company.com)、李四(lisi@gmail.com)
议题1(2024-03-15 截止):项目预算 50000元,已花费 12800元
议题2(2024-04-01 截止):采购设备 8500元
下次会议:2024-05-20
"""
参考答案:
import re
text = """
会议记录:
日期:2024-03-11,地点:北京
参会人:张三(zhangsan@company.com)、李四(lisi@gmail.com)
议题1(2024-03-15 截止):项目预算 50000元,已花费 12800元
议题2(2024-04-01 截止):采购设备 8500元
下次会议:2024-05-20
"""
# 1. 提取所有日期
dates = re.findall(r"d{4}-d{2}-d{2}", text)
print("日期:", dates)
# ['2024-03-11', '2024-03-15', '2024-04-01', '2024-05-20']
# 2. 提取所有金额
amounts = re.findall(r"d+元", text)
print("金额:", amounts)
# ['50000元', '12800元', '8500元']
# 3. 提取所有邮箱
emails = re.findall(r"[a-zA-Z0-9._%+-]+@[a-zA-Z0-9.-]+.[a-zA-Z]{2,}", text)
print("邮箱:", emails)
# ['zhangsan@company.com', 'lisi@gmail.com']
关键点:
re.findall(pattern, text):返回所有匹配的字符串列表d{4}:恰好 4 个数字;d+:1 个或更多数字- 正则字符串建议用
r"..."原始字符串
11. re——数据清洗
题目: 有一批从表单收集来的手机号,格式混乱,请用正则表达式统一清洗成纯数字格式(只保留数字):
raw_phones = [
"138-1234-5678",
"(021) 8765-4321",
" 13987654321 ",
"010 - 88886666",
"400 800 1234",
]
参考答案:
import re
raw_phones = [
"138-1234-5678",
"(021) 8765-4321",
" 13987654321 ",
"010 - 88886666",
"400 800 1234",
]
print("清洗后的号码:")
for raw in raw_phones:
# re.sub 把所有非数字字符替换为空字符串
clean = re.sub(r"D", "", raw) # D 表示非数字字符
print(f" {raw:25} → {clean}")
输出:
清洗后的号码:
138-1234-5678 → 13812345678
(021) 8765-4321 → 02187654321
13987654321 → 13987654321
010 - 88886666 → 01088886666
400 800 1234 → 4008001234
关键点:
re.sub(pattern, replacement, string):把匹配的部分替换为指定字符串D:匹配任何非数字字符(等同于[^0-9])
12. time——代码性能对比
题目: 比较下面两种求 1~1000000 之和的方法的运行时间,用 time.perf_counter() 计时:
- 用
for循环累加 - 用内置
sum()+range()
参考答案:
import time
N = 1_000_000
# 方法一:for 循环
start = time.perf_counter()
total = 0
for i in range(1, N + 1):
total += i
end = time.perf_counter()
t1 = end - start
print(f"for 循环:结果={total},耗时={t1:.6f} 秒")
# 方法二:sum() + range()
start = time.perf_counter()
total = sum(range(1, N + 1))
end = time.perf_counter()
t2 = end - start
print(f"sum(): 结果={total},耗时={t2:.6f} 秒")
# 对比
print(f"nsum() 比 for 循环快 {t1 / t2:.1f} 倍")
示例输出:
for 循环:结果=500000500000,耗时=0.045231 秒
sum(): 结果=500000500000,耗时=0.008764 秒
sum() 比 for 循环快 5.2 倍
关键点:
time.perf_counter()精度比time.time()更高,适合代码计时- 内置的
sum()是用 C 实现的,比纯 Python 的for循环快很多
13. itertools——生成彩票号码
题目: 用 itertools.combinations 生成所有可能的彩票号码组合(从 1~10 中选 3 个数字),统计共有多少种组合,并随机抽取一组作为”中奖号码”。
参考答案:
import itertools
import random
numbers = range(1, 11) # 1 到 10
# 生成所有 C(10, 3) = 120 种组合
all_combinations = list(itertools.combinations(numbers, 3))
print(f"从 1~10 中选 3 个数字,共有 {len(all_combinations)} 种组合")
print(f"前 5 种:{all_combinations[:5]}")
# 随机抽取一组作为中奖号码
winning = random.choice(all_combinations)
print(f"n本期中奖号码:{winning}")
# 让用户也选一组
my_pick = tuple(sorted(random.sample(range(1, 11), 3)))
print(f"你选的号码:{my_pick}")
if my_pick == winning:
print("恭喜中奖!")
else:
print(f"很遗憾,没有中奖。中奖号码是 {winning}")
关键点:
itertools.combinations(可迭代对象, r):从中选 r 个,不考虑顺序,不重复itertools.permutations:考虑顺序(排列);combinations:不考虑顺序(组合)
14. 综合题——个人日记本(json + datetime + os)
题目: 实现一个简单的命令行日记本:
- 每条日记自动记录当前时间
- 日记保存在
diary.json文件中(不存在时自动创建) - 支持两个功能:添加日记、查看所有日记
参考答案:
import json
import os
from datetime import datetime
DIARY_FILE = "diary.json"
def load_diary():
"""加载日记文件,不存在则返回空列表"""
if not os.path.exists(DIARY_FILE):
return []
with open(DIARY_FILE, "r", encoding="utf-8") as f:
return json.load(f)
def save_diary(entries):
"""保存日记到文件"""
with open(DIARY_FILE, "w", encoding="utf-8") as f:
json.dump(entries, f, ensure_ascii=False, indent=2)
def add_entry(content):
"""添加一条日记"""
entries = load_diary()
entry = {
"time": datetime.now().strftime("%Y-%m-%d %H:%M:%S"),
"content": content
}
entries.append(entry)
save_diary(entries)
print(f"日记已保存!({entry['time']})")
def show_all():
"""显示所有日记"""
entries = load_diary()
if not entries:
print("暂无日记记录。")
return
print(f"n=== 我的日记(共 {len(entries)} 条)===")
for i, entry in enumerate(entries, 1):
print(f"n【第 {i} 条】{entry['time']}")
print(f" {entry['content']}")
print()
# 测试
add_entry("今天学习了 Python 标准库,感觉收获很多!")
add_entry("用 json 模块实现了日记持久化存储,很有成就感。")
show_all()
运行结果:
日记已保存!(2024-03-11 14:30:25)
日记已保存!(2024-03-11 14:30:25)
=== 我的日记(共 2 条)===
【第 1 条】2024-03-11 14:30:25
今天学习了 Python 标准库,感觉收获很多!
【第 2 条】2024-03-11 14:30:25
用 json 模块实现了日记持久化存储,很有成就感。
15. 综合挑战——学生成绩分析系统
题目: 综合运用 random、datetime、json、collections、math 模块,实现一个学生成绩分析系统:
- 用
random随机生成 10 名学生的三科成绩(语文、数学、英语,每科 60~100 分) - 将成绩数据保存到
students.json - 计算每名学生的平均分
- 用
Counter统计各分数段的人数(60-69、70-79、80-89、90-100) - 找出平均分最高和最低的学生
- 打印完整分析报告,并在报告顶部显示生成时间(用
datetime)
参考答案:
import random
import json
import math
from datetime import datetime
from collections import Counter
# ① 生成随机成绩数据
names = ["张三", "李四", "王五", "赵六", "孙七", "周八", "吴九", "郑十", "钱一", "冯二"]
subjects = ["语文", "数学", "英语"]
students = []
for name in names:
scores = {subject: random.randint(60, 100) for subject in subjects}
avg = sum(scores.values()) / len(scores)
students.append({
"name": name,
"scores": scores,
"average": round(avg, 1)
})
# ② 保存到 JSON 文件
with open("students.json", "w", encoding="utf-8") as f:
json.dump(students, f, ensure_ascii=False, indent=2)
# ③ 统计分数段
def get_grade(avg):
if avg >= 90: return "90-100"
elif avg >= 80: return "80-89"
elif avg >= 70: return "70-79"
else: return "60-69"
grade_counter = Counter(get_grade(s["average"]) for s in students)
# ④ 找最高/最低
best = max(students, key=lambda s: s["average"])
worst = min(students, key=lambda s: s["average"])
# ⑤ 打印完整报告
now = datetime.now().strftime("%Y年%m月%d日 %H:%M:%S")
print(f"╔{'═'*42}╗")
print(f"║{'学生成绩分析报告':^40}║")
print(f"║{'生成时间:' + now:^40}║")
print(f"╚{'═'*42}╝")
print(f"n{'姓名':^6} {'语文':^6} {'数学':^6} {'英语':^6} {'平均分':^6}")
print("-" * 38)
for s in sorted(students, key=lambda x: x["average"], reverse=True):
sc = s["scores"]
print(f"{s['name']:^6} {sc['语文']:^6} {sc['数学']:^6} {sc['英语']:^6} {s['average']:^6}")
print(f"n分数段分布:")
for grade in ["90-100", "80-89", "70-79", "60-69"]:
count = grade_counter.get(grade, 0)
bar = "■" * count
print(f" {grade} 分:{count:2} 人 {bar}")
print(f"n平均分最高:{best['name']}({best['average']} 分)")
print(f"平均分最低:{worst['name']}({worst['average']} 分)")
# 计算全班总平均分(用 math.fsum 精度更高)
all_avgs = [s["average"] for s in students]
class_avg = math.fsum(all_avgs) / len(all_avgs)
print(f"全班平均分:{class_avg:.1f} 分")
示例输出:
╔══════════════════════════════════════════╗
║ 学生成绩分析报告 ║
║ 生成时间:2024年03月11日 14:30:25 ║
╚══════════════════════════════════════════╝
姓名 语文 数学 英语 平均分
--------------------------------------
王五 96 91 88 91.7
张三 88 92 85 88.3
...
分数段分布:
90-100 分: 2 人 ■■
80-89 分: 5 人 ■■■■■
70-79 分: 2 人 ■■
60-69 分: 1 人 ■
平均分最高:王五(91.7 分)
平均分最低:钱一(64.3 分)
全班平均分:80.6 分
涉及知识点:
| 模块 | 用途 |
|---|---|
random.randint |
生成随机成绩 |
json.dump / load |
保存和读取成绩文件 |
datetime.now |
报告生成时间 |
collections.Counter |
统计分数段分布 |
math.fsum |
高精度求和 |
知识点速查
| 题号 | 模块 | 考查点 |
|---|---|---|
| 1 | random |
choice、sample 随机抽选 |
| 2 | random |
randint + while 循环游戏 |
| 3 | datetime |
strptime 解析 + strftime 格式化 |
| 4 | datetime |
date.today()、两日期相减、timedelta.days |
| 5 | pathlib |
iterdir()、suffix、rglob() |
| 6 | math |
sqrt、pi、海伦公式 |
| 7 | json |
dump/load 读写文件,ensure_ascii |
| 8 | collections |
Counter 词频统计,most_common |
| 9 | collections |
defaultdict(list) 分组 |
| 10 | re |
findall 提取日期/金额/邮箱 |
| 11 | re |
sub 数据清洗,D 非数字匹配 |
| 12 | time |
perf_counter 代码计时对比 |
| 13 | itertools |
combinations 生成组合 |
| 14 | json + datetime + os |
命令行日记本综合应用 |
| 15 | 多模块综合 | 成绩分析系统(random + json + datetime + Counter + math) |