```python # 原始数据 chinese_scores = [["张三", "S001", 85], ["李四", "S002", 92], ["王五", "S003", 78]] math_scores = [["张三", "S001", 90], ["李四", "S002", 87], ["王五", "S003", 85]] english_scores = [["S001", "张三", 88], ["S002", "李四", 85], ["S003", "王五", 80]] def build_score_dict(score_list, key_index, score_type): """将成绩列表转换为字典""" score_dict = {} for item in score_list: if key_index == 1: # 以学号为键 sid = item[1] name = item[0] score = item[2] else: # 以姓名为键 name = item[1] sid = item[0] score = item[2] # 使用学号作为唯一标识符 if sid not in score_dict: score_dict[sid] = {"姓名": name} score_dict[sid][score_type] = score return score_dict # 构建各科目字典 chinese_dict = build_score_dict(chinese_scores, 1, "语文") math_dict = build_score_dict(math_scores, 1, "数学") english_dict = build_score_dict(english_scores, 0, "英语") # 合并字典 def merge_score_dicts(*dicts): """合并多个成绩字典""" merged = {} all_sids = set() # 收集所有学号 for score_dict in dicts: all_sids.update(score_dict.keys()) # 合并数据 for sid in sorted(all_sids): student_data = {} for score_dict in dicts: if sid in score_dict: student_data.update(score_dict[sid]) merged[sid] = student_data return merged # 执行合并 final_dict = merge_score_dicts(chinese_dict, math_dict, english_dict) print(final_dict) ``` ## 两种方案的对比 | 特性 | List 方案 | Dict 方案 | |------|-----------|-----------| | 数据访问 | 通过索引,容易出错 | 通过键名,语义清晰 | | 数据完整性 | 需要严格对齐 | 自动处理缺失数据 | | 扩展性 | 添加新科目需要修改代码 | 添加新科目简单 | | 可读性 | 较差 | 较好 | | 性能 | O(n) | O(1) 查找 | | 内存使用 | 较低 | 较高 | ## 实际应用示例 ### 示例1:处理不完整数据 ```python # 有学生缺考的情况 chinese_scores = [["张三", "S001", 85], ["李四", "S002", 92]] math_scores = [["张三", "S001", 90], ["王五", "S003", 85]] english_scores = [["S001", "张三", 88], ["S002", "李四", 85]] # 使用字典方案可以优雅处理 chinese_dict = build_score_dict(chinese_scores, 1, "语文") math_dict = build_score_dict(math_scores, 1, "数学") english_dict = build_score_dict(english_scores, 0, "英语") final_dict = merge_score_dicts(chinese_dict, math_dict, english_dict) print("处理不完整数据的结果:") for sid, scores in final_dict.items(): print(f"{sid}: {scores}") ``` ### 示例2:使用字典推导式简化代码 ```python # 使用字典推导式构建字典 def build_score_dict_comprehension(score_list, key_index, score_type): """使用字典推导式构建成绩字典""" if key_index == 1: return {item[1]: {"姓名": item[0], score_type: item[2]} for item in score_list} else: return {item[0]: {"姓名": item[1], score_type: item[2]} for item in score_list} # 更简洁的合并函数 def merge_dicts_simple(*dicts): """简化版字典合并""" merged = {} for d in dicts: for key, value in d.items(): if key not in merged: merged[key] = {} merged[key].update(value) return merged ``` ## 练习题目 ### 练习1:计算平均分 基于合并后的字典数据,计算每个学生的平均分: ```python def calculate_average_scores(score_dict): """计算每个学生的平均分""" result = {} for sid, scores in score_dict.items(): total = 0 count = 0 for subject, score in scores.items(): if subject != "姓名" and isinstance(score, (int, float)): total += score count += 1 result[sid] = { "姓名": scores["姓名"], "平均分": round(total / count, 2) if count > 0 else 0 } return result # 测试计算平均分 averages = calculate_average_scores(final_dict) print("平均分统计:") for sid, avg in averages.items(): print(f"{sid}: {avg}") ``` ### 练习2:找出最高分学生 ```python def find_top_student(score_dict, subject=None): """找出指定科目或总分的最高分学生""" if subject: # 指定科目的最高分 top_score = -1 top_student = None for sid, scores in score_dict.items(): if subject in scores and scores[subject] > top_score: top_score = scores[subject] top_student = scores["姓名"] return top_student, top_score else: # 总分的最高分 top_total = -1 top_student = None for sid, scores in score_dict.items(): total = sum(score for key, score in scores.items() if key != "姓名" and isinstance(score, (int, float))) if total > top_total: top_total = total top_student = scores["姓名"] return top_student, top_total # 测试找出最高分学生 top_math = find_top_student(final_dict, "数学") top_overall = find_top_student(final_dict) print(f"数学最高分: {top_math}") print(f"总分最高分: {top_overall}") ``` ## 总结 **成功之处** - List 方案展示了基础的数据处理流程和问题分析思路 - Dict 方案提供了更优雅、高效的解决方案 - 通过对比展示了不同数据结构的适用场景和性能特点 - 提供了实际应用示例和练习题目,加深理解 **需要改进的地方** - List 方案对数据格式要求严格,容错性差 - 需要处理字段顺序不一致的问题 - 缺乏完善的错误处理机制 - 代码可维护性有待提高 ## 最佳实践建议 1. **选择合适的数据结构**:对于键值对数据,优先考虑字典 2. **统一数据格式**:在数据收集阶段就规范格式,避免后续处理麻烦 3. **添加验证机制**:检查数据完整性和一致性,处理异常情况 4. **考虑扩展性**:设计能够处理未来需求变化的方案 5. **代码可读性**:使用有意义的变量名和函数名,添加必要的注释 6. **性能考虑**:根据数据规模选择合适的数据结构和算法 ## 扩展思考 1. 如果数据量非常大(百万级别),应该如何优化? 2. 如果需要支持动态添加新科目,如何设计数据结构? 3. 如何将处理结果保存到文件或数据库中? 4. 如何为这个功能编写单元测试? 通过这个案例,我们不仅学会了如何将列表转换为字典,更重要的是理解了不同数据结构的选择对代码质量、性能和可维护性的影响。