Python 现代开发学习笔记

(十八)综合示例与独立练习

1. 阅读时长统计

任务(自拟):第一行输入统计天数,接下来每天输入一行非负整数分钟数。输出总时长、平均时长、达到 30 分钟的天数和最长的一天。没有任何记录时,平均时长显示为 0.00。

输入:

4
20
35
0
45

先手算四轮状态:

读到的分钟数 累计时长 达标天数 最长时长
20 20 0 20
35 55 1 35
0 55 1 35
45 100 2 45
# reading_summary.py:每读一条记录,就更新累计值、达标数与最大值。
days = int(input())
total = 0
completed = 0
longest = 0
for day in range(days):
    minutes = int(input())
    total += minutes
    if minutes >= 30:
        completed += 1
    if minutes > longest:
        longest = minutes

# 由已有的累计状态计算平均值,零条记录时直接给出 0。
average = total / days if days > 0 else 0
print("总时长", total)
print(f"平均时长 {average:.2f}")
print("达标天数", completed)
print("最长时长", longest)

输出:

总时长 100
平均时长 25.00
达标天数 2
最长时长 45

每条记录被读取一次,工作量为 O(n)O(n);除输入本身外,只保存几个累计状态,额外空间为 O(1)O(1)。若后续还要查看每天的记录,就另加列表保存数据,空间变为 O(n)O(n),原有统计更新仍能复用。

练习:增加“连续达标的最长天数”。用 35、40、0、45、50、60 手算,应得到 3;思考未达标那天需要重置哪个状态。再测试零天、全部未达标、全部达标三种记录。

2. 书名词频与稳定输出

任务(自拟):输入一行用空白分隔的书名,统计每个书名出现次数,按书名的字符串顺序输出。这里一个书名是一项,例子使用 Python、NumPy 等不含空白的名称。

# title_counts.py:输入拆成书名,字典累加次数,排序后统一输出。
titles = input().split()
counts = {}
for title in titles:
    counts[title] = counts.get(title, 0) + 1
for title in sorted(counts):
    print(title, counts[title])

输入 Python NumPy Python Pygame Python,输出:

NumPy 1
Pygame 1
Python 3

字典负责把同名记录归到一起,排序负责最终输出顺序。设总项数为 n,不同书名数量为 k,平均统计工作量为 O(n)O(n),排序为 O(klog⁡k)O(k\log k)。文本切分和比较还要读取书名中的字符,书名更长时,这部分工作也相应增加。

练习:改成出现次数降序、同次数按书名升序。输入 B A B A C,预期输出顺序为 A 2、B 2、C 1。先列出每条结果的比较键,再选择已经学过的元组排序方式。

3. 阅读清单菜单

任务(自拟):维护一份书架,支持下列命令:

命令 动作
add 书名 加入未读书籍;已有书名时保留原状态并提示
done 书名 把已有书籍标为已读;不存在时提示
list 按加入顺序显示编号、书名和阅读状态
quit 结束程序

先把一行命令分开。split(maxsplit=1) 最多切一次,因此带空格的书名也会保存在第二项:

# 只切分“命令”和“其余内容”,让书名内部的空格继续保留。
line = input().strip()
parts = line.split(maxsplit=1)
print(parts)

输入 add Python 入门,得到 ['add', 'Python 入门']。整行只有空白时,parts 是空列表,此时先提示再开始下一轮,不能直接读取第一项。

再确定状态的保存方式:字典键保存完整书名,值保存是否读完。加入是写入 False,完成是把值改为 True;重复加入时保留已有值。

# 用同一份字典跟踪“加入”与“读完”两次动作。
books = {}
books["Python 入门"] = False
print(books)
books["Python 入门"] = True
# items 提供键值对,条件表达式把布尔状态转成显示文字。
for title, finished in books.items():
    status = "已读" if finished else "未读"
    print(title, status)
菜单从读取命令到更新状态的过程

流程按读取、检查、分派与更新展开,只有 quit 结束循环。完整可运行程序在 reading_menu.py。代码按这四个职责分段并加上注释,先手动跟踪图中的一轮,再运行完整程序。

输入:

add Python 入门
add NumPy
done Python 入门
list
quit

输出:

已加入 Python 入门
已加入 NumPy
已标记 Python 入门
1 Python 入门 已读
2 NumPy 未读
已退出

把 done Django、重复的 add NumPy、只有 add 的命令和空行分别放进去,核对提示后原字典是否保留正确状态。练习可以增加 remove 书名 与“只列未读书籍”命令,先为新增动作写出状态变化,再接到命令分派中。

笔记正文与全部题解 · Ctrl / ⌘ K