# 原始数据
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:处理不完整数据

# 有学生缺考的情况
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:使用字典推导式简化代码

# 使用字典推导式构建字典
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:计算平均分

基于合并后的字典数据,计算每个学生的平均分:

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:找出最高分学生

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. 如何为这个功能编写单元测试?

通过这个案例,我们不仅学会了如何将列表转换为字典,更重要的是理解了不同数据结构的选择对代码质量、性能和可维护性的影响。