递归遍历食谱配料的Python函数返回字典冗余问题排查
解决递归配料遍历中字典冗余的问题
我一眼就看出问题所在了——这是Python里常见的可变默认参数陷阱!
问题根源
你把ingredients_list=dict()作为函数的默认参数,而Python的可变默认参数(比如字典、列表)是在函数定义时就创建实例,不是每次调用函数时创建。这意味着所有递归调用都会共享同一个字典对象,每次递归都会往这个字典里追加内容,最终返回的字典自然会包含大量之前递归过程中积累的冗余数据。而你的打印语句只输出当前处理的配料,所以看起来是对的,但字典一直在偷偷累积。
修复方案
我们只需要把默认参数改成None,然后在函数内部初始化字典,确保每次调用(包括递归)都能正确管理字典的生命周期:
def get_prep_ingredients_recursively(quantity, menu_item_preps, prep_id, ingredients_list=None, **kwargs): # 初始化空字典:如果没有传入字典,就创建新的;否则用传入的 ingredients_list_results = ingredients_list if ingredients_list is not None else {} for Prep_item in menu_item_preps: if Prep_item['ID'] == prep_id: for prep_ingredient in Prep_item['SubItems']: if prep_ingredient['ItemTypeName'] == "Prep": # 递归调用时传递当前的字典,确保数据累积正确 ingredients_list_results = get_prep_ingredients_recursively( quantity / Prep_item['ProdQuantity'], menu_item_preps, prep_ingredient['ItemID'], ingredients_list_results ) else: amount = (prep_ingredient['UsageNet'] / Prep_item['ProdQuantity'] * quantity) ingredient_id = prep_ingredient['ItemID'] # 可选:如果同一个配料多次出现,累加数量(根据你的需求调整) if ingredient_id in ingredients_list_results: ingredients_list_results[ingredient_id]['Ingredient_Amount'] += amount else: ingredients_list_results[ingredient_id] = { 'Name': prep_ingredient['ItemName'], 'Ingredient_Amount': amount } print(f"{prep_ingredient['ItemName']} -- {amount}") return ingredients_list_results
关键修改点说明
- 默认参数改为None:避免了所有调用共享同一个字典实例的问题
- 内部初始化字典:确保首次调用时创建新字典,递归调用时传递当前字典以累积数据
- 可选的数量累加:如果同一个基础配料在多个递归层级出现,这段逻辑会合并它的总数量(如果你的需求是覆盖而不是累加,可以删掉这个判断)
现在你再运行代码,返回的字典就只会包含当前遍历路径下的所有配料,不会有冗余内容了。
内容的提问来源于stack exchange,提问作者zcstover
相关产品推荐
相关产品推荐

