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

Python遍历嵌套字典填充列表时遇'str'对象无'items'属性错误

解决AttributeError: 'str' object has no attribute 'items'问题及代码优化

错误根源

当剩余空间不足4时,你生成的available_objects_list是嵌套字典结构,而非首次选择时的字典列表。遍历字典时默认迭代的是键(字符串类型),导致i变成字符串,调用i.items()自然触发属性错误。

核心问题梳理

  • 数据类型不一致:首次选择时available_objects_list是列表(如[{"Item Name": "A1", ...}, ...]),后续选择时变成字典(如{"Option1": {"Common": [...]}}),遍历逻辑不兼容。
  • 条件判断顺序错误:elif (max_amount_limit - selected_objects_size) < 4会覆盖elif <3的情况,因为所有小于3的数值必然小于4,导致第三个分支永远无法执行。
  • 语法错误:
    • objects_chosen is None是判断语句,应改为赋值objects_chosen = None
    • objects_chosen - "Done"是减法操作,应改为赋值objects_chosen = "Done"
  • 状态重置问题:stage1_selection中每次循环都重置user_stage1_objects = [],会丢失之前选择的对象。

修复后的代码

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
    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")
        return

    while objects_chosen is None:
        remaining_space = max_amount_limit - selected_objects_size
        # 调整条件顺序,优先判断更小的剩余空间
        if remaining_space > 3:
            available_objects_list = chosen_timeframe["Option1"]["Common"]
        elif remaining_space < 3:
            available_objects_list = [
                item for item in chosen_timeframe["Option1"]["Common"]
                if item["Size"] < 3
            ]
        elif remaining_space < 4:
            available_objects_list = [
                item for item in chosen_timeframe["Option1"]["Common"]
                if item["Size"] < 4
            ]

        if not available_objects_list:
            print("No available objects to select!")
            objects_chosen = "Done"
            continue

        # 统一遍历字典列表,避免类型错误
        object_itr = 0
        for item in available_objects_list:
            print(f"{object_itr} - ")
            for key, val in item.items():
                print(f"    {key}: {val}")
            object_itr += 1

        # 增加输入校验,避免无效值
        try:
            chosen_object_index = int(input("> "))
            if chosen_object_index < 0 or chosen_object_index >= len(available_objects_list):
                print("Invalid index, try again")
                continue
        except ValueError:
            print("Please enter a valid number")
            continue

        selected_item = available_objects_list[chosen_object_index]
        user_stage1_objects.append(selected_item["Item Name"])
        selected_objects_size += selected_item["Size"]

        if selected_objects_size == max_amount_limit:
            print("Space is full!")
            objects_chosen = "Done"
        else:
            continue_choice = input(f"""
        You have {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_choice == "1":
                objects_chosen = None
            elif continue_choice == "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
    selected_objects_size = 0
    user_stage1_objects = []

    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":
        print("Skipping Option1 selection")

    return user_stage1_objects

result = fill_chosen_objects()
print("Selected objects:", result)

修复说明

  1. 统一数据类型:无论剩余空间多少,available_objects_list始终保持为字典列表,确保遍历逻辑一致。
  2. 调整条件顺序:先判断remaining_space <3,再判断<4,保证每个分支都能被正确触发。
  3. 修复语法错误:修正赋值语句的错误写法。
  4. 保留已选状态:移除user_stage1_objects = []的重置操作,保留用户之前的选择。
  5. 增加输入校验:处理非数字输入和无效索引的情况,提升代码健壮性。

内容的提问来源于stack exchange,提问作者Moonlyte Demon

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.06.27 10:09:49