|
|
你想实现的是通过「年级 + 班级」的组合键,快速获取对应班级的学生数组,核心就是用嵌套的键值表(哈希表) 来存储,外层键对应年级、内层键对应班级,内层的值就是该班的学生数组,这个需求特别清晰,用 Python 实现起来很直观,我会用 Python 的字典(dict,Python 原生的哈希表 / 键值表) 来完成,同时定义学生的自定义数据类型,贴合你的需求。
第一步:先定义学生的自定义数据类型
Python 中自定义数据类型,新手用 **dataclasses** 最方便(简洁、不用写繁琐的初始化代码),也可以用传统的类,我两种都给你,选dataclasses就够了。
[Python] 纯文本查看 复制代码 # 推荐:用dataclasses定义学生自定义类型(Python3.7+支持,主流环境都满足)
from dataclasses import dataclass
# 学生类:包含学号、姓名、成绩等你需要的信息,可自行增删字段
@dataclass
class Student:
stu_id: str # 学号
name: str # 姓名
score: float # 成绩(示例)
# 传统类写法(兼容低版本Python,效果和上面一致)
# class Student:
# def __init__(self, stu_id, name, score):
# self.stu_id = stu_id
# self.name = name
# self.score = score
第二步:核心实现 —— 嵌套字典存储「年级 - 班级 - 学生数组」
Python 的字典是键值对结构,正好满足哈希表的需求,我们设计两层嵌套字典:
- 外层字典:键 = 年级(int 类型,比如 1、2、3),值 = 该年级的班级字典
- 内层字典:键 = 班级(int 类型,比如 1、2、3),值 = 该班级的学生数组(list 列表,Python 的数组用 list 实现)
这种结构的优势:通过「年级 key→班级 key」直接定位,cha询速度是哈希表的 O (1),特别快,完全符合你的需求。
完整可运行代码示例
包含初始化存储容器、添加班级学生、通过年级 + 班级cha询、遍历所有班级等核心操作,直接复制就能用:
[Python] 纯文本查看 复制代码 from dataclasses import dataclass
# 1. 定义学生自定义数据类型
@dataclass
class Student:
stu_id: str # 学号
name: str # 姓名
score: float # 成绩(可根据需求增删字段,比如性别、年龄)
# 2. 初始化核心存储容器:嵌套字典(年级→班级→学生数组)
# 外层dict:key=年级(int),value=内层dict
# 内层dict:key=班级(int),value=学生数组(list[Student])
school_dict = {}
# 3. 封装工具函数(简化操作,避免重复代码)
def add_class_students(grade: int, cls: int, students: list[Student]):
"""
向存储容器中添加「某年级某班」的学生数组
:param grade: 年级(int)
:param cls: 班级(int),避免和Python关键字class冲突,用cls代替
:param students: 该班的学生数组(list[Student])
"""
# 如果年级不存在,先初始化该年级的班级字典
if grade not in school_dict:
school_dict[grade] = {}
# 给该年级的指定班级赋值学生数组(覆盖原有值,若需追加可改:school_dict[grade][cls].extend(students))
school_dict[grade][cls] = students
def get_class_students(grade: int, cls: int) -> list[Student] | None:
"""
通过「年级+班级」cha询对应班级的学生数组
:param grade: 年级(int)
:param cls: 班级(int)
:return: 学生数组(list[Student]),若年级/班级不存在返回None
"""
# 先判断年级是否存在,再判断班级是否存在,避免键不存在报错
if grade in school_dict and cls in school_dict[grade]:
return school_dict[grade][cls]
return None
# ------------------- 测试使用 -------------------
if __name__ == "__main__":
# 模拟创建1年级1班的学生数组
cls1_1 = [
Student(stu_id="001", name="张三", score=95.5),
Student(stu_id="002", name="李四", score=88.0),
Student(stu_id="003", name="王五", score=92.0)
]
# 模拟创建1年级2班的学生数组
cls1_2 = [
Student(stu_id="004", name="赵六", score=79.5),
Student(stu_id="005", name="孙七", score=90.0)
]
# 模拟创建2年级1班的学生数组
cls2_1 = [
Student(stu_id="006", name="周八", score=85.0)
]
# 1. 添加班级学生到存储容器
add_class_students(grade=1, cls=1, students=cls1_1)
add_class_students(grade=1, cls=2, students=cls1_2)
add_class_students(grade=2, cls=1, students=cls2_1)
# 2. 核心需求:通过「年级+班级」cha询学生数组
print("===== 1年级1班学生 =====")
students_1_1 = get_class_students(1, 1)
if students_1_1: # 判空,避免None调用遍历报错
for stu in students_1_1:
print(f"学号:{stu.stu_id},姓名:{stu.name},成绩:{stu.score}")
print("\n===== 2年级1班学生 =====")
students_2_1 = get_class_students(2, 1)
if students_2_1:
for stu in students_2_1:
print(f"学号:{stu.stu_id},姓名:{stu.name},成绩:{stu.score}")
# 3. cha询不存在的班级(比如3年级1班)
print("\n===== 3年级1班学生 =====")
students_3_1 = get_class_students(3, 1)
print(students_3_1) # 输出None
# 4. 遍历学校所有年级和班级的学生
print("\n===== 遍历全校所有班级 =====")
for grade, cls_dict in school_dict.items():
for cls, students in cls_dict.items():
print(f"\n{grade}年级{cls}班:")
for stu in students:
print(f" {stu.name}(学号:{stu.stu_id},成绩:{stu.score})")
关键补充说明
- 学生数组的修改:如果需要修改某个班级的学生(比如新增、删除、修改学生信息),直接cha询到数组后操作即可,因为 Python 的列表是可变对象,字典中存储的是列表的引用,修改后字典中的值会同步更新:
[Python] 纯文本查看 复制代码 # 给1年级1班新增一个学生
students_1_1 = get_class_students(1, 1)
if students_1_1:
students_1_1.append(Student(stu_id="006", name="钱九", score=86.5))
键的类型:年级和班级建议用int 整数(比如 1、2),比字符串(比如 "一年级"、"1 班")更节省内存、cha询更快,若需要显示成文字,后续格式化即可。异常处理:如果需要更健壮的代码,可以在工具函数中添加参数校验(比如年级 / 班级不能为 0 或负数、学生数组不能为空),避免无效数据存入总结一下~
核心实现就两种方式,按需选择即可,都是 Python 原生哈希表(字典)的经典用法:
- 嵌套字典:{年级: {班级: 学生数组}},逻辑层级清晰,适合需要单独遍历「某年级所有班级」的场景;
- 单层字典:{(年级, 班级): 学生数组},代码更简洁,cha询一步到位,适合简单的「年级 + 班级」精准cha询。
|
|