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 = Noneobjects_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)
修复说明
- 统一数据类型:无论剩余空间多少,
available_objects_list始终保持为字典列表,确保遍历逻辑一致。 - 调整条件顺序:先判断
remaining_space <3,再判断<4,保证每个分支都能被正确触发。 - 修复语法错误:修正赋值语句的错误写法。
- 保留已选状态:移除
user_stage1_objects = []的重置操作,保留用户之前的选择。 - 增加输入校验:处理非数字输入和无效索引的情况,提升代码健壮性。
内容的提问来源于stack exchange,提问作者Moonlyte Demon
相关产品推荐
相关产品推荐

