Python - 迭代嵌套字典以根据值填充列表 - 遇到“str”对象没有属性“items”

问题描述 投票:0回答:1

我正在创建一个代码,该代码应该允许用户从列表中选择多个对象。 每个用户都有分配的空间量,每个对象都有指定的大小。 我试图根据对象的稀有性填充列表,并且仅显示大小等于或小于用户留下的分配空间的项目。

但是,一旦用户选择了一个对象并且列表仅更新为剩余大小范围内的对象,用于显示列表的代码将不再起作用,并且会收到以下错误:

AttributeError:“str”对象没有属性“items”

user_stage1_objects = []
selected_objects_size = 0

timeframe1 = {
    "Option1": {
        "Common": [{"Item Name": "A1", "Size": "3"}, {"Item Name": "A2", "Size": 4}],
        "Uncommon": [{"Item Name": "B1", "Size": 2}, {"Item Name": "B2", "Size": 1}]
    },
    "Option2": {
        "Common": [{"Item Name": "C1", "Size": 3}, {"Item Name": "C2", "Size": 1}],
        "Uncommon": [{"Item Name": "D1", "Size": 2}, {"Item Name": "D2", "Size": 4}]
    }
}

timeframe2 = {
    "Option1": {
        "Common": [{"Item Name": "A1", "Size": "3"}, {"Item Name": "A3", "Size": 2}],
        "Uncommon": [{"Item Name": "B1", "Size": 2}, {"Item Name": "B2", "Size": 1}]
    },
    "Option2": {
        "Common": [{"Item Name": "C2", "Size": 1}, {"Item Name": "C3", "Size": 3}],
        "Uncommon": [{"Item Name": "D1", "Size": 2}, {"Item Name": "D2", "Size": 4}]
    }
}


def stage1_selection():
    global max_amount_limit, selected_objects_size, available_objects_list, user_stage1_objects

    objects_chosen = None

    user_stage1_objects = []
    available_objects_list = []

    timeframe_choice = input("""
        Select Timeframe1 or Timeframe2
        1 - Timeframe1
        2 - Timeframe2
        > """)
    if timeframe_choice == "1":
        chosen_timeframe = timeframe1
    elif timeframe_choice == "2":
        chosen_timeframe = timeframe2
    else:
        print("Not a valid choice, try again")

    while objects_chosen is None:
        if (max_amount_limit - selected_objects_size) > 3:
            if chosen_timeframe == timeframe1:
                available_objects_list = timeframe1["Option1"]["Common"]
            elif chosen_timeframe == timeframe2:
                available_objects_list = timeframe2["Option2"]["Common"]
        elif (max_amount_limit - selected_objects_size) < 4:
            available_objects_list = []
            if chosen_timeframe == timeframe1:
                available_objects_list = {
                    options: {
                        rarity: [
                            item for item in items
                                if item["Size"] < 4
                        ]
                            for rarity, items in options.items()
                                if rarity == "Common"
                    }
                        for option, options in timeframe1.items()
                            if option == "Option1"
                }
            elif chosen_timeframe == timeframe2:
                available_objects_list = {
                    options: {
                        rarity: [
                            item for item in items
                                if item["Size"] < 4
                        ]
                            for rarity, items in options.items()
                                if rarity == "Common"
                    }
                        for option, options in timeframe2.items()
                            if option == "Option1"
                }
        elif (max_amount_limit - selected_objects_size) < 3:
            available_objects_list = []
            if chosen_timeframe == timeframe1:
                available_objects_list = {
                    options: {
                        rarity: [
                            item for item in items
                                if item["Size"] < 3
                        ]
                            for rarity, items in options.items()
                                if rarity == "Common"
                    }
                        for option, options in timeframe1.items()
                            if option == "Option1"
                }
            elif chosen_timeframe == timeframe2:
                available_objects_list = {
                    options: {
                        rarity: [
                            item for item in items
                                if item["Size"] < 3
                        ]
                            for rarity, items in options.items()
                                if rarity == "Common"
                    }
                        for option, options in timeframe2.items()
                            if option == "Option1"
                }

        object_availability = available_objects_list
        object_itr = 0
        for i in object_availability:
            print(object_itr, end=' - ')
            for key, val in i.items():
                print(key, ": ", val, end='\n    ')
            print()
            object_itr = object_itr+1

        chosen_object_index = input("> ")
        chosen_object_index = int(chosen_object_index)
        user_stage1_objects.append(object_availability[chosen_object_index]["Item Name"])

        selected_objects_size = selected_objects_size + object_availability[chosen_object_index]["Size"]

        if max_amount_limit == selected_objects_size:
            objects_chosen = "Done"
        else:
            continue_object_selection = input("""
        You have """+str(int(max_amount_limit - selected_objects_size))+""" amounts left.

        Do you want to select more objects from Option1, or move on to Option2?
        1 - Continue with Option1
        2 - Move on to Option2

        >""")

            if continue_object_selection == "1":
                objects_chosen is None
            elif continue_object_selection == "2":
                objects_chosen - "Done"
            else:
                print("Not a valid choice, try again")

def fill_chosen_objects():
    global max_amount_limit, selected_objects_size, available_objects_list, user_stage1_objects

    max_amount_limit = 5

    selecting_objects = input("""
        Would you like to see available choices from Option1?

        1 - Yes
        2 - No

    > """)
    
    if selecting_objects == "1":
        stage1_selection()
    elif selecting_objects == "2":
        objects_chosen = "Done"

    return user_stage1_objects

fill_chosen_objects()

很抱歉在这里放置了很长的代码,但我之前尝试过发布较小的代码部分,但当应用于较大的代码库时,有效的方法似乎不起作用。

基本上,一旦考虑了 max_amount_limit(他们已经选择的累积项目),用户就不应该看到尺寸大于其剩余尺寸的对象。

我能够第一次看到对象列表,但当我尝试查看列表以选择第二个对象时,它崩溃了。

这一行出现 AttributeError: 'str' object has no attribute 'items' 错误

for key, val in i.items():

谢谢你

python list dictionary while-loop iteration
1个回答
0
投票

您多次将

available_objects_list
变量分配给字典值。

当迭代

for i in object_availability:
中的字典时,
i
将被设置为你的字典的键,在你的情况下是字符串。

替换例如:

available_objects_list = {
    options: {
        rarity: [
            item for item in items
                if item["Size"] < 4
        ]
            for rarity, items in options.items()
                if rarity == "Common"
    }
        for option, options in timeframe1.items()
            if option == "Option1"
}

available_objects_list = [
    {
        options: {
            rarity: [
                item for item in items
                    if item["Size"] < 4
            ]
                for rarity, items in options.items()
                    if rarity == "Common"
        }
            for option, options in timeframe1.items()
                if option == "Option1"
    }
]
© www.soinside.com 2019 - 2024. All rights reserved.