使用csv.DictReader读取游戏分数CSV时,如何构建指定结构的分数字典并解决键值访问错误
使用csv.DictReader读取游戏分数CSV时,如何构建指定结构的分数字典并解决键值访问错误
嘿,我来帮你理清这里的问题,一步步解决你的困惑。首先得明确:csv.DictReader返回的每一行是字典对象,不是列表,所以你不能用数字索引(比如row[0]、row[1])去访问内容,这是你大部分错误的根源。咱们先逐个分析错误,再给出正确的实现。
先拆解你遇到的错误原因
KeyError: 0
你的代码里写了score_sheet[row[0]] = {row[game]:row[game[1]],这里有两个问题:row[0]:row是字典,键是CSV的表头(比如name、Game_1),没有数字0这个键,应该用row['name']来获取用户名。row[game[1]]:game是游戏名(比如Game_1),game[1]取的是字符串的第二个字符(比如Game_1的第二个字符是a),显然row里没有这个键,完全是逻辑错误。
KeyError: 1
score_sheet[row[0]] = row[1]同样犯了“用数字索引访问字典”的错误,row没有1这个键,你需要访问的是除了name之外的游戏列。ValueError: too many values to unpack (expected 2)
for row, value in reader:这种写法不对,因为reader迭代出来的是完整的行字典,不是键值对。如果要遍历字典的键值对,应该在每行里写for key, value in row.items()。
正确实现两种目标格式
根据你给出的期望输出,我提供两种常见的实现方式:
方式1:名字对应游戏-分数的字典(最常用)
这种结构是{name: {game1: score1, game2: score2, ...}},代码如下:
import csv score_sheet = {} with open("scores.txt") as scores_file: reader = csv.DictReader(scores_file) # 获取所有游戏列的名称(跳过第一个name列) list_of_games = reader.fieldnames[1:] for row in reader: name = row['name'] # 为当前用户创建游戏分数字典 game_scores = {} for game in list_of_games: game_scores[game] = row[game] # 把用户和对应的分数存入总字典 score_sheet[name] = game_scores print(score_sheet)
输出结果:
{ 'James': {'Game_1': '3', 'Game_2': '7', 'Game_3': '4'}, 'Charles': {'Game_1': '2', 'Game_2': '3', 'Game_3': '8'}, 'Bob': {'Game_1': '6', 'Game_2': '2', 'Game_3': '4'} }
方式2:名字对应单个游戏-分数字典的列表(你提到的可选格式)
如果需要{name: [{game1: score1}, {game2: score2}, ...]}这种结构,只需要稍微修改内层逻辑:
import csv score_sheet = {} with open("scores.txt") as scores_file: reader = csv.DictReader(scores_file) list_of_games = reader.fieldnames[1:] for row in reader: name = row['name'] game_score_list = [] for game in list_of_games: # 每个游戏分数单独存为一个字典 game_score_list.append({game: row[game]}) score_sheet[name] = game_score_list print(score_sheet)
输出结果:
{ 'James': [{'Game_1': '3'}, {'Game_2': '7'}, {'Game_3': '4'}], 'Charles': [{'Game_1': '2'}, {'Game_2': '3'}, {'Game_3': '8'}], 'Bob': [{'Game_1': '6'}, {'Game_2': '2'}, {'Game_3': '4'}] }
额外小技巧:访问字典中的特定值
比如要获取James的Game_2分数,用第一种结构的话可以直接写:
print(score_sheet['James']['Game_2']) # 输出7
用第二种结构的话,需要遍历列表找到对应的游戏:
for game_dict in score_sheet['James']: if 'Game_2' in game_dict: print(game_dict['Game_2']) # 输出7
内容来源于stack exchange
相关产品推荐
相关产品推荐

