8.19实验:足球球队花名册程序(字典)报错求助
足球球队花名册程序(字典)排障求助
作业要求
- 输入5组球员球衣号(0-99)和评分(1-9),存入字典并按球衣号升序输出花名册;
- 实现菜单功能,包含添加、删除、更新评分、输出指定评分以上球员、输出花名册、退出选项;
- 依次实现各菜单选项功能。
我的代码
Roster1={ 'player 1':[], 'player 2':[], 'player 3':[], 'player 4':[], 'player 5':[] } for n in range(5): jersey=int(input("Enter player %s"%(n+1)+"'s jersey number:\n")) rating=int(input("Enter player %s"%(n+1)+"'s rating:\n\n")) Roster1[f"player {n+1}"]=(int(jersey),int(rating)) sorted_roster = dict(sorted(Roster1.items(), key=lambda x: x[1][0])) userchoice='' print("ROSTER") for player, (jersey, rating) in sorted_roster.items(): print(f'Jersey number: {jersey}, Rating: {rating}') print('') print("MENU") print("a - Add player") print("d - Remove player") print("u - Update player rating") print("r - Output players above a rating") print("o - Output roster") print("q - Quit") print('\nChoose an option:') while userchoice != 'q': userchoice=str(input()) if userchoice=='q': break elif userchoice=='o': print() print("ROSTER") for player, (jersey, rating) in sorted_roster.items(): print(f'Jersey number: {jersey}, Rating: {rating}') continue elif userchoice=='a': addjersey=str(input("Enter a jersey number:\n")) addrate=str(input("Enter a new rating for player:\n")) sorted_roster["player 6"]=(addjersey,addrate) sorted_roster = dict(sorted(Roster1.items(), key=lambda x: x[1][0])) print("ROSTER") for player, (jersey, rating) in sorted_roster.items(): print(f'Jersey number: {jersey}, Rating: {rating}') print('') print("MENU") print("a - Add player") print("d - Remove player") print("u - Update player rating") print("r - Output players above a rating") print("o - Output roster") print("q - Quit") print('\nChoose an option:') elif userchoice=='d': removejersey=int(input("Enter a jersey number:\n")) for player,(jersey,rating) in sorted_roster.items(): if jersey==removejersey: del sorted_roster[player] print() for player, (jersey, rating) in sorted_roster.items(): print(f'Jersey number: {jersey}, Rating: {rating}') print('') print("MENU") print("a - Add player") print("d - Remove player") print("u - Update player rating") print("r - Output players above a rating") print("o - Output roster") print("q - Quit") print('\nChoose an option:') elif userchoice=='r': above=int(input("Enter a rating\n")) print(f'ABOVE {above}') sorted_roster = dict(sorted(Roster1.items(), key=lambda x: x[1][0])) for player, (jersey, rating) in sorted_roster.items(): if rating>above: print(f'Jersey number: {jersey}, Rating: {rating}') print('') print("MENU") print("a - Add player") print("d - Remove player") print("u - Update player rating") print("r - Output players above a rating") print("o - Output roster") print("q - Quit") print('\nChoose an option:')
报错情况
运行时错误:遍历字典期间字典大小发生变化(RuntimeError: dictionary changed size during iteration)
问题排查与修复方案
1. 核心报错原因
删除球员的代码中,直接遍历sorted_roster.items()并同时删除字典元素,Python不允许在遍历字典的同时修改其大小,因此触发RuntimeError。
2. 其他潜在问题
- 添加球员时,将新球员存入
sorted_roster后又重新从Roster1排序,导致新添加的球员丢失(Roster1未同步更新);同时球衣号和评分被存为字符串,后续排序、比较会触发类型错误。 - 输出指定评分以上球员时,重新从
Roster1排序,会丢失之前的添加/删除操作结果。 - 未实现更新评分的功能。
- 球员命名硬编码(如
player 6),多次添加会覆盖已有球员。
3. 修复后的完整代码
# 用球衣号作为字典键,便于查找、修改、删除操作 roster = {} # 输入5组球员信息 for n in range(5): jersey = int(input(f"Enter player {n+1}'s jersey number:\n")) rating = int(input(f"Enter player {n+1}'s rating:\n\n")) roster[jersey] = rating # 封装排序输出花名册的函数,避免重复代码 def print_roster(): print("\nROSTER") # 按球衣号升序遍历输出 for jersey in sorted(roster.keys()): print(f'Jersey number: {jersey}, Rating: {roster[jersey]}') # 打印初始花名册 print_roster() # 菜单循环 while True: print('\nMENU') print("a - Add player") print("d - Remove player") print("u - Update player rating") print("r - Output players above a rating") print("o - Output roster") print("q - Quit") choice = input('\nChoose an option: ').strip().lower() if choice == 'q': break elif choice == 'o': print_roster() elif choice == 'a': jersey = int(input("Enter a jersey number:\n")) rating = int(input("Enter a new rating for player:\n")) roster[jersey] = rating print_roster() elif choice == 'd': remove_jersey = int(input("Enter a jersey number:\n")) # 通过键直接判断并删除,避免遍历字典时修改其大小 if remove_jersey in roster: del roster[remove_jersey] print_roster() elif choice == 'u': jersey = int(input("Enter a jersey number:\n")) if jersey in roster: new_rating = int(input("Enter a new rating:\n")) roster[jersey] = new_rating else: print("Player not found.") print_roster() elif choice == 'r': above_rating = int(input("Enter a rating:\n")) print(f"\nABOVE {above_rating}") for jersey in sorted(roster.keys()): if roster[jersey] > above_rating: print(f'Jersey number: {jersey}, Rating: {roster[jersey]}') else: print("Invalid option, please try again.")
修复说明
- 改用球衣号作为字典键,符合业务逻辑,查找、修改、删除操作更高效,无需遍历整个字典。
- 封装
print_roster()函数,避免重复代码,保证输出始终按球衣号升序排列。 - 删除球员时直接通过键判断并删除,解决遍历字典时修改大小的RuntimeError。
- 统一将输入的球衣号和评分转为整数,避免类型错误。
- 修复添加球员时数据丢失的问题,直接更新主字典
roster。 - 补充实现更新评分的功能。
- 增加无效输入提示,提升程序健壮性。
内容的提问来源于stack exchange,提问作者Grace Mcpadden
相关产品推荐
相关产品推荐

