Python TypeError: string indices must be integers报错排查求助
问题排查:Python计算学生作业得分时的TypeError错误
处理第一条学生记录(arto)时代码运行正常,但处理第二条记录(erkki)时触发TypeError: string indices must be integers, not 'str',错误出在print(maxs>wank[line[0]])语句。
报错追踪
Traceback (most recent call last): File "c:\Users\User\AppData\Local\tmc\vscode\mooc-programming-24\part07-15_who_cheated_2\src\who_cheated_2.py", line 51, in <module> print(final_points()) ^^^^^^^^^^^^^^ File "c:\Users\User\AppData\Local\tmc\vscode\mooc-programming-24\part07-15_who_cheated_2\src\who_cheated_2.py", line 29, in final_points print(maxs>wank[line[0]]) ~~~~^^^^^^^^^ TypeError: string indices must be integers, not 'str'
代码实现
# Write your solution here from datetime import timedelta,datetime import csv def final_points(): wank = {} with open("start_times.csv") as rocky: for line in csv.reader(rocky,delimiter=";"): pol = datetime.strptime(line[1],"%H:%M") wank[line[0]] = pol students = {} rankings = {"1":0,"2":0,"3":0,"4":0,"5":0,"6":0,"7":0,"8":0} with open("submissions.csv") as monks: for line in csv.reader(monks,delimiter=";"): rap = datetime.strptime(line[3],"%H:%M") maxs = rap - timedelta(hours=3) print(line[0]) print(maxs>wank[line[0]]) if maxs>wank[line[0]]: continue wank = line[1] if line[0] not in students: students[line[0]] = rankings print(students) if students[line[0]][line[1]]<int(line[2]): students[line[0]][line[1]] = int(line[2]) for key in students: students[key] = sum(students[key].values()) return students if __name__ == "__main__": print(final_points())
CSV文件格式
start_times.csv
matti;13:33 erkki;15:13 antti;15:49 emilia;13:37 henrik;15:01 arto;17:01 esko;14:24 kjell;13:34 jyrki;16:12 etc..
submissions.csv
arto;1;4;19:12 erkki;2;2;16:03 matti;7;3;16:21 jyrki;1;3;17:43 etc...
问题原因与修复方案
核心错误1:字典被意外覆盖
代码中wank原本是存储学生开始时间的字典,但在处理submissions.csv的循环里,你写了wank = line[1],这直接把wank从字典改成了当前行的作业编号字符串(比如处理arto时,wank变成了"1")。处理第一条记录时wank还是字典,所以正常;到第二条erkki时,wank已经是字符串,执行wank[line[0]]就会报错——字符串的索引只能是整数,而line[0]是学生名字字符串,触发TypeError。
核心错误2:共享字典导致数据混乱
students[line[0]] = rankings是直接引用同一个rankings字典,所有学生的分数会共享这个字典,修改一个学生的分数会影响所有学生,必须改为创建字典的副本。
修复后的代码
from datetime import timedelta, datetime import csv def final_points(): # 存储学生的开始时间,键是学生名,值是datetime对象 start_times = {} with open("start_times.csv") as rocky: for line in csv.reader(rocky, delimiter=";"): start_time = datetime.strptime(line[1], "%H:%M") start_times[line[0]] = start_time students = {} # 每个学生的作业初始分数模板 score_template = {"1": 0, "2": 0, "3": 0, "4": 0, "5": 0, "6": 0, "7": 0, "8": 0} with open("submissions.csv") as monks: for line in csv.reader(monks, delimiter=";"): student_name = line[0] exercise_num = line[1] score = int(line[2]) submit_time = datetime.strptime(line[3], "%H:%M") # 计算提交时间的3小时前,判断是否超过开始时间 three_hours_before = submit_time - timedelta(hours=3) if three_hours_before > start_times[student_name]: continue # 为学生创建独立的分数字典(用副本,避免共享) if student_name not in students: students[student_name] = score_template.copy() # 更新对应作业的最高分数 if students[student_name][exercise_num] < score: students[student_name][exercise_num] = score # 计算每个学生的总分 for student in students: students[student] = sum(students[student].values()) return students if __name__ == "__main__": print(final_points())
修复说明
- 重命名
wank为start_times,变量名更清晰,避免混淆。 - 删除了错误的
wank = line[1]语句,不再覆盖存储开始时间的字典。 - 将
students[line[0]] = rankings改为students[student_name] = score_template.copy(),每个学生拥有独立的分数字典,避免数据互相影响。 - 拆分了line的元素到单独变量,代码可读性更高。
内容的提问来源于stack exchange,提问作者Jaime III Andrade
相关产品推荐
相关产品推荐

