Python生成大学课表时while循环失效出现课时重叠及报错问题排查
问题根本原因
- 数据存储结构不匹配:你往
t_sections对应班级的列表中存储的元素是[课程id, 包含单个Slot对象的列表]的嵌套结构,但你在while判断时直接拿Slot(day, slot, 1)和列表中的嵌套元素做相等判断,触发Slot.__eq__时传入的对比对象是列表,自然没有day属性,抛出AttributeError。 - 之前出现大量课时重叠的原因:未给
Slot类添加__eq__方法时,Python默认对自定义类实例做相等判断时对比的是内存地址,就算两个Slot的day和slot完全一致,也会被判定为不同对象,导致while循环的校验逻辑完全失效。
修复方案
我们可以通过提取已占用时段的元组做校验,既避免类型匹配问题,又能提升校验效率,修改后的排课代码如下:
import random t_sections = {} for sec in sections: # 截取父班级名称 parent_section = sec.section[:5] # 初始化班级排课列表 if parent_section not in t_sections: t_sections[parent_section] = [] # 提取当前班级已占用的所有时段(day, slot)元组 used_slots = set() for course_info in t_sections[parent_section]: slot_obj = course_info[1][0] used_slots.add((slot_obj.day, slot_obj.slot)) # 为当前课程排2次课 for _ in range(2): day = random.randint(1, 5) slot = random.randint(1, 5) # 校验时段未被占用 while (day, slot) in used_slots: day = random.randint(1, 5) slot = random.randint(1, 5) # 新增排课记录,保留你原有的存储结构 new_slot = Slot(day, slot, 1) t_sections[parent_section].append([sec.id, [new_slot]]) # 更新已占用时段集合 used_slots.add((day, slot))
可选优化方案
如果要保留用Slot对象直接做in判断的逻辑,你需要单独为每个班级维护一个仅存储Slot对象的已用列表,不要和课程信息混合存储,示例如下:
import random t_sections = {} # 单独维护每个班级的已用Slot列表 used_slot_map = {} for sec in sections: parent_section = sec.section[:5] if parent_section not in t_sections: t_sections[parent_section] = [] used_slot_map[parent_section] = [] for _ in range(2): new_slot = Slot(random.randint(1,5), random.randint(1,5), 1) while new_slot in used_slot_map[parent_section]: new_slot = Slot(random.randint(1,5), random.randint(1,5), 1) t_sections[parent_section].append([sec.id, [new_slot]]) used_slot_map[parent_section].append(new_slot)
两种方案都可以保证同一班级的Day+Slot组合唯一,不会出现课时重叠问题。
内容的提问来源于stack exchange,提问作者Awais Shahid
相关产品推荐
相关产品推荐

