如何基于用户输入的宏量营养素键排序嵌套字典中的产品?
问题:CS50 Python期末项目宏量营养素排序推荐功能实现
我正在完成CS50《Python编程入门》的期末项目,需要实现四个功能:计算基础代谢率、格式化产品列表、展示用户指定产品的营养值,以及根据用户指定的宏量营养素对产品排序推荐,目前卡在最后一项。
我用两层嵌套字典存储产品及其营养值:
products = { "almonds": {"protein": 6.0, "fat": 14.2, "carbs": 6.1, "fiber": 3.5, "calories": 164}, "banana": {"protein": 1.3, "fat": 0.4, "carbs": 27.0, "fiber": 3.1, "calories": 105}, "buckwheat": {"protein": 5.7, "fat": 1.0, "carbs": 34.0, "fiber": 4.5, "calories": 155}, "ground beef": {"protein": 24.0, "fat": 13, "carbs": 0, "fiber": 0, "calories": 218} }
需求是实现一个函数:询问用户指定的宏量营养素(可选值为protein、fat、carbs、fiber或calories,均为嵌套字典的键),遍历products字典后输出该营养素含量Top3的产品。
我不想把营养值改成嵌套列表(觉得不够直观),而且已经有一个用于获取特定产品营养值的_get_nested_val函数,希望复用它来实现排序功能:
def _get_nested_val(data, *args): if args and data: element = args[0] if element: value = data.get(element) return value if len(args) == 1 else _get_nested_val(value, *args[1:])
期望运行效果:
# $ What do you want the program to do? suggest # $ Based on what macronutrient would you like the products to be suggested? protein # The following products are high in protein: Ground Beef, Almonds, Buckwheat
查了相关资料还是没搞定,求帮助。
解决方案
步骤1:实现用户输入验证
首先要确保用户输入的宏量营养素是合法的,避免程序报错:
def get_valid_macronutrient(): valid_keys = ["protein", "fat", "carbs", "fiber", "calories"] while True: nutrient = input("Based on what macronutrient would you like the products to be suggested? ").strip().lower() if nutrient in valid_keys: return nutrient print(f"Invalid input. Please choose from: {', '.join(valid_keys)}")
步骤2:复用_get_nested_val实现排序
利用Python的sorted()函数,结合_get_nested_val获取每个产品的目标营养素值,进行降序排序后取前3个:
def suggest_top_products(products, nutrient): # 按指定营养素降序排序产品(键值对元组) sorted_products = sorted( products.items(), key=lambda item: _get_nested_val(item[1], nutrient), reverse=True ) # 提取Top3产品名称并格式化(首字母大写) top3_names = [product_name.title() for product_name, _ in sorted_products[:3]] # 输出结果 print(f"The following products are high in {nutrient}: {', '.join(top3_names)}")
步骤3:整合功能到主流程
把上述函数整合到程序主逻辑中:
def main(): while True: action = input("What do you want the program to do? ").strip().lower() if action == "suggest": nutrient = get_valid_macronutrient() suggest_top_products(products, nutrient) break # 如需循环执行可移除break # 此处可添加其他功能分支(如计算BMR、展示产品列表等) else: print("Invalid action. Available actions: suggest") if __name__ == "__main__": main()
代码说明
sorted(products.items(), key=..., reverse=True):将字典转换为(产品名, 营养字典)的元组列表,用lambda表达式调用_get_nested_val获取目标营养素值作为排序依据,降序排列确保含量最高的产品在前。title()方法将产品名转换为首字母大写格式,让输出更规范美观。- 输入验证函数避免用户输入非法键,防止
_get_nested_val返回None导致排序异常。
内容的提问来源于stack exchange,提问作者Jötunn
相关产品推荐
相关产品推荐

