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

使用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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.16 00:25:20