You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

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())

修复说明

  1. 重命名wank为start_times,变量名更清晰,避免混淆。
  2. 删除了错误的wank = line[1]语句,不再覆盖存储开始时间的字典。
  3. 将students[line[0]] = rankings改为students[student_name] = score_template.copy(),每个学生拥有独立的分数字典,避免数据互相影响。
  4. 拆分了line的元素到单独变量,代码可读性更高。

内容的提问来源于stack exchange,提问作者Jaime III Andrade

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.06.30 13:07:53