使用Dictionary替代List管理卡牌集合时遇TypeError问题求助
卡牌集合管理程序Dictionary重构错误修复
错误原因分析
触发TypeError: 'int' object is not subscriptable的核心原因:
- 原代码基于List实现,
display_cards函数接收卡牌字典组成的列表;重构为Dictionary后,传入的是{ID: 卡牌字典}结构的字典,直接遍历该字典时拿到的是键(即ID,int类型),而非卡牌字典,执行target['ID']时自然报错。 load_card_collection_file函数存在变量名错误:定义了card_collection_item但赋值给未定义的collection_item,会触发NameError。
修复方案及代码调整
1. 修复load_card_collection_file函数
修正变量名错误,确保卡牌字典正确构建:
def load_card_collection_file(file_name): max_id = -1 try: card_collection = {} card_collection_file = open(file_name, "r") field_names = card_collection_file.readline().rstrip().split(",") for item in card_collection_file: field_values = item.rstrip().split(",") card_collection_item = {} for index in range(len(field_values)): if (field_names[index] == "Available") or (field_names[index] == "Copies") or (field_names[index] == "ID"): card_collection_item[field_names[index]] = int(field_values[index]) else: card_collection_item[field_names[index]] = field_values[index] card_collection[card_collection_item["ID"]] = card_collection_item max_id = max(max_id, card_collection_item["ID"]) card_collection_file.close() except FileNotFoundError: print("File not found when attempting to read", file_name) return None except IOError: print("Error in data file when reading", file_name) return None return card_collection, max_id
2. 适配display_cards函数
区分输入类型,确保遍历的是卡牌字典:
def display_cards(items, sports_or_pokemon): # 若输入是字典,提取values()转为卡牌列表 if isinstance(items, dict): items = list(items.values()) if len(items) == 0 and sports_or_pokemon: print('No related sports cards are found.') elif len(items) == 0 and not sports_or_pokemon: print('No related pokemon cards are found.') else: for target in items: print('ID: {0}'.format(target['ID'])) print('Name: {0}'.format(target['Name'])) print('Year: {0}'.format(target['Year'])) print('Copies: {0}'.format(target['Copies'])) print('Available: {0}'.format(target['Available'])) if(sports_or_pokemon): print('Sport: {0}'.format(target['Sport'])) print('Publisher: {0}'.format(target['Publisher'])) print('Series: {0}'.format(target['Series'])) else: print('Edition: {0}'.format(target['Edition'])) print('Rarity: {0}'.format(target['Rarity'])) print('Generation: {0}'.format(target['Generation'])) print('')
3. 适配其他依赖List的函数
check_in函数(改用字典直接查找)
def check_in(card_library_collections): card_id = int(input('Enter the ID for the card: ')) # 优先查找sports集合,再查找pokemon集合 target_card = card_library_collections['sports'].get(card_id) or card_library_collections['pokemon'].get(card_id) if not target_card: print('Your card ID is invalid') return if target_card['Available'] < target_card['Copies']: target_card['Available'] += 1 print('Your check in has succeeded.') is_sport = 'Sport' in target_card display_cards([target_card], is_sport) elif target_card['Available'] == target_card['Copies']: print('All copies are already available, so this card cannot be checked in.')
check_out函数(改用字典直接查找)
def check_out(card_library_collections): card_id = int(input('Enter the ID for the card you wish to check out: ')) target_card = card_library_collections['sports'].get(card_id) or card_library_collections['pokemon'].get(card_id) if not target_card: print('Your card ID is invalid') return if target_card['Available'] > 0: target_card['Available'] -= 1 print('Your check out has succeeded.') is_sport = 'Sport' in target_card display_cards([target_card], is_sport) elif target_card['Available'] == 0: print('No copies of the card are available for check out.')
query_cards函数(遍历字典values)
def query_cards(card_collection, sports_or_pokemon_query): query_str = input('Enter a query string to use for the search: ') if len(query_str) == 0: print('Invalid query string.') return card_list = [] query_str = query_str.lower() # 遍历字典的values获取卡牌数据 for item in card_collection.values(): if (sports_or_pokemon_query and (query_str in item['Name'].lower() or query_str in item['Sport'].lower() or query_str in item['Publisher'].lower())): card_list.append(item) elif (not sports_or_pokemon_query and (query_str in item['Name'].lower() or query_str in item['Edition'].lower() or query_str in item['Generation'].lower())): card_list.append(item) display_cards(card_list, sports_or_pokemon_query)
add_sports_card函数(改用字典赋值)
def add_sports_card(sports_collection, max_existing_id): print('Please enter the following attributes for the new sports card.') new_card = {} max_existing_id += 1 new_card['ID'] = max_existing_id new_card['Name'] = input('Name: ') new_card['Sport'] = input('Sport: ') new_card['Publisher'] = input('Publisher: ') new_card['Series'] = input('Series: ') new_card['Year'] = int(input('Year: ')) new_card['Copies'] = int(input('Copies: ')) new_card['Available'] = new_card['Copies'] print('You have entered the following details:') display_cards([new_card], True) cancel_prompt = input("Press enter to add this item to the collection. Enter 'x' to cancel.") if not cancel_prompt: sports_collection[new_card['ID']] = new_card return max_existing_id elif cancel_prompt == 'x': return max_existing_id - 1
add_pokemon_card函数(改用字典赋值)
def add_pokemon_card(pokemon_collection, max_existing_id): print('Please enter the following attributes for the new card.') new_card = {} max_existing_id += 1 new_card['ID'] = max_existing_id new_card['Name'] = input('Name: ') new_card['Edition'] = input('Edition: ') new_card['Rarity'] = input('Rarity: ') new_card['Generation'] = input('Generation: ') new_card['Year'] = int(input('Year: ')) new_card['Copies'] = int(input('Copies: ')) new_card['Available'] = new_card['Copies'] print('You have entered the following data:') display_cards([new_card], False) cancel_prompt = input("Press enter to add this item to the collection. Enter 'x' to cancel.") if not cancel_prompt: pokemon_collection[new_card['ID']] = new_card return max_existing_id elif cancel_prompt == 'x': return max_existing_id - 1
main函数(修正参数错误与函数调用)
def main(): def load_card_collections(): sports_card_collection, max_sport_id = load_card_collection_file("sportscards.csv") pokemon_cards_collection, max_poke_id = load_card_collection_file("pokecards.csv") if sports_card_collection is None or pokemon_cards_collection is None: return None, None return {"sports": sports_card_collection, "pokemon": pokemon_cards_collection}, max(max_sport_id, max_poke_id) card_library_collections, max_existing_id = load_card_collections() if card_library_collections is None: print("The collections did not load.") return else: print("The collections were loaded.") operation = menu_prompts() while operation != "x": if operation == "cci": check_in(card_library_collections) elif operation == "cco": check_out(card_library_collections) elif operation == "asc": max_existing_id = add_sports_card(card_library_collections["sports"], max_existing_id) elif operation == "apc": max_existing_id = add_pokemon_card(card_library_collections["pokemon"], max_existing_id) elif operation == "dsc": display_cards(card_library_collections["sports"], True) elif operation == "dpc": display_cards(card_library_collections["pokemon"], False) elif operation == "qsc": query_cards(card_library_collections["sports"], True) elif operation == "qpc": query_cards(card_library_collections["pokemon"], False) else: print("Invalid command") operation = menu_prompts()
其他补充修正
load_card_collections函数中原调用的load_collection不存在,改为load_card_collection_file- 移除无用的
sports_or_pokemon函数,直接通过卡牌字典的键判断类型 - 修正
query_cards中未定义变量res,改为card_list
内容的提问来源于stack exchange,提问作者user20303539
相关产品推荐
相关产品推荐

