← 返回 Day 7 正文

Day 7 · 练习与清单

Day 007 — 元组(Tuple)练习与检查清单

📌 完成每个练习后,在 [ ] 中打 [x]


✅ 今日完成清单

概念理解

基本操作

元组拆包

namedtuple

列表 vs 元组

实战


📝 练习题

练习 1:实现三维向量运算库

用 namedtuple 或 typing.NamedTuple 定义一个 Vector3D 类型,实现以下函数:

python
# TODO: 定义 Vector3D,包含 x, y, z

def vector_add(v1, v2):
    """向量加法"""
    pass

def dot_product(v1, v2):
    """点积:v1·v2 = x1*x2 + y1*y2 + z1*z2"""
    pass

def cross_product(v1, v2):
    """叉积:v1 × v2 = (y1*z2 - z1*y2, z1*x2 - x1*z2, x1*y2 - y1*x2)"""
    pass

def vector_length(v):
    """向量长度"""
    pass

def normalize(v):
    """向量归一化(单位向量)"""
    pass

# 测试数据
v1 = Vector3D(1, 2, 3)
v2 = Vector3D(4, 5, 6)

print(vector_add(v1, v2))   # 预期: Vector3D(5, 7, 9)
print(dot_product(v1, v2))  # 预期: 32
print(cross_product(v1, v2)) # 预期: Vector3D(-3, 6, -3)
print(vector_length(v1))    # 预期: 3.74...

提示:Vector3D 继承 NamedTuple,上面所有函数都可以作为方法写在类内部!


练习 2:学生成绩管理系统

不使用数据库,用元组和 namedtuple 实现一个简单的学生成绩管理系统。

python
from collections import namedtuple
from typing import List

# 定义 Student 类型(含有 name, chinese, math, english 四个字段)
# TODO: 你的代码

def average_score(student):
    """计算平均分"""
    pass

def rank_students(students: List) -> List:
    """按总分排序(从高到低)"""
    pass

def top_student(students: List):
    """返回第一名"""
    pass

# 测试数据
students = [
    Student("Alice", 90, 85, 92),
    Student("Bob", 78, 88, 80),
    Student("Charlie", 95, 92, 98),
]

# 输出每个学生的信息
for s in students:
    print(f"{s.name}: 总分={s.chinese + s.math + s.english}, 平均分={average_score(s):.1f}")

# 输出排名
print("\n排名:")
for rank, s in enumerate(rank_students(students), 1):
    total = s.chinese + s.math + s.english
    print(f"第{rank}名: {s.name} ({total}分)")

扩展挑战:为 Student 添加 _replace 来更新某一门成绩。


练习 3:文本分析器

给定以下文本,用元组拆包技巧完成字符串解析任务:

python
text = "Alice:85,Bob:92,Charlie:78,Diana:95"

# 1. 将文本解析为 (name, score) 元组列表
# 2. 找出最高分的同学
# 3. 计算平均分
# 4. 输出格式化的成绩报告

# TODO: 你的代码

# 预期输出:
# Alice: 85
# Bob: 92
# Charlie: 78
# Diana: 95
# 最高分: Diana (95)
# 平均分: 87.5

提示:"Alice:85".split(":") 返回 ["Alice", "85"],可以用拆包接收。


练习 4:路径点集合

python
from collections import namedtuple
from typing import List

# Point 类型
Point = namedtuple('Point', ['x', 'y'])

# 一条路径由一系列点组成
path = [
    Point(0, 0),
    Point(1, 2),
    Point(3, 5),
    Point(6, 1),
    Point(10, 4),
]

# 1. 计算路径总长度(从第一个点到最后一个点的连线距离之和)
# 2. 找到路径中某段距离最长的两个相邻点
# 3. 压缩路径:如果某段距离小于 2.0,跳过该点(简化路径)

def total_path_length(points: List[Point]) -> float:
    """计算路径总长度"""
    pass

def longest_segment(points: List[Point]) -> tuple:
    """返回距离最长的 (点A, 点B, 距离)"""
    pass

def simplify_path(points: List[Point], min_dist: float = 2.0) -> List[Point]:
    """简化和压缩路径"""
    pass

# TODO: 实现上述函数并测试

练习 5:数据流聚合器(进阶)

python
from collections import namedtuple

# 传感器数据流
SensorReading = namedtuple('SensorReading', ['timestamp', 'temperature', 'humidity'])

readings = [
    SensorReading(1, 25.3, 60.1),
    SensorReading(2, 25.7, 59.8),
    SensorReading(3, 26.1, 59.2),
    SensorReading(4, 26.8, 58.5),
    SensorReading(5, 27.2, 57.9),
]

# 1. 计算温度与湿度的平均值
# 2. 找到温度最高和最低的采样点
# 3. 如果温度变化率超过 0.5/单位时间,标记为异常
# 4. 使用 zip() 和拆包从多个元组列表中提取温度序列

# TODO: 你的代码

📖 参考链接


💡 今日重点回顾

元组的不可变性 → 数据安全 + 可哈希
        ↓
  可做字典键  → 坐标、配置常量、数据库记录
        ↓
  namedtuple  → 自描述性 + 可拆包 + 轻量不可变数据结构
        ↓
  性能优势     → 内存小、创建快、迭代快
        ↓
  适合场景     → 固定结构数据、多返回值、常量集合