# 原始数据
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 方案对数据格式要求严格,容错性差
需要处理字段顺序不一致的问题
缺乏完善的错误处理机制
代码可维护性有待提高
最佳实践建议¶
选择合适的数据结构:对于键值对数据,优先考虑字典
统一数据格式:在数据收集阶段就规范格式,避免后续处理麻烦
添加验证机制:检查数据完整性和一致性,处理异常情况
考虑扩展性:设计能够处理未来需求变化的方案
代码可读性:使用有意义的变量名和函数名,添加必要的注释
性能考虑:根据数据规模选择合适的数据结构和算法
扩展思考¶
如果数据量非常大(百万级别),应该如何优化?
如果需要支持动态添加新科目,如何设计数据结构?
如何将处理结果保存到文件或数据库中?
如何为这个功能编写单元测试?
通过这个案例,我们不仅学会了如何将列表转换为字典,更重要的是理解了不同数据结构的选择对代码质量、性能和可维护性的影响。