Python开发餐食计划程序时如何避免用大量if语句校验多参数
多参数校验实现方案
方案1:逐项校验快速失败(最简单易读)
无需嵌套if,对每一项限制单独判断,只要有一项不满足就直接跳过当前餐食:
for meal in meals: is_qualified = True # 过敏限制:用户选"是"则过滤含过敏原的餐食 if restrictions[0] and meal.getAllergy(): is_qualified = False # 健康限制:用户选"是"则过滤非健康餐食 if restrictions[1] and not meal.getHealthy(): is_qualified = False # 无麸质限制:用户选"是"则过滤含麸质的餐食 if restrictions[2] and not meal.getGluten(): is_qualified = False # 素食限制:用户选"是"则过滤非素食餐食 if restrictions[3] and not meal.getVegitarian(): is_qualified = False # 烹饪时间限制:用户没选无限制则过滤超时餐食 if restrictions[4] != 1000 and meal.getCookTime() > restrictions[4]: is_qualified = False # 所有限制都满足才加入结果列表 if is_qualified: mealsR.append(meal)
这个写法逻辑直观,没有任何嵌套,新增限制只要照着加一行if判断即可。
方案2:规则抽象(易扩展易维护)
如果后续会频繁新增限制条件,可以把规则和校验逻辑抽象成列表,新增限制仅需添加规则项,无需修改校验逻辑:
def getRestrictedMeals(meals): mealsR = [] # 定义规则列表:每一项为(用户限制值, 餐食校验函数) rules = [] # 收集过敏限制 print("Would you like only foods you aren't allergic to?\n1. Yes\n2. No") rules.append( (getRestHelp(int(input("Please choose an option: "))), lambda meal: not meal.getAllergy()) ) # 收集健康限制 print("\nWould you like only healthy foods?\n1. Yes\n2. No") rules.append( (getRestHelp(int(input("Please choose an option: "))), lambda meal: meal.getHealthy()) ) # 收集无麸质限制 print("\nWould you like only Gluten Free foods?\n1. Yes\n2. No") rules.append( (getRestHelp(int(input("Please choose an option: "))), lambda meal: meal.getGluten()) ) # 收集素食限制 print("\nWould you like only Vegitarian foods?\n1. Yes\n2. No") rules.append( (getRestHelp(int(input("Please choose an option: "))), lambda meal: meal.getVegitarian()) ) # 收集烹饪时间限制 print("\nWhat is the longest cook time you want?\nPlease enter 1000 for any cook time.") time_limit = int(input()) rules.append( (time_limit, lambda meal: meal.getCookTime() <= time_limit if time_limit != 1000 else True) ) # 统一校验所有餐食 for meal in meals: valid = True for restrict_val, check in rules: # 用户未开启该限制则跳过校验 if not restrict_val: continue # 校验不通过直接跳出 if not check(meal): valid = False break if valid: mealsR.append(meal) return mealsR
额外优化建议
你当前代码中提前收集所有餐食属性到facts列表的逻辑可以删掉,直接在校验时取餐食对应属性即可,减少不必要的内存占用。
内容的提问来源于stack exchange,提问作者Alayna Juneau
相关产品推荐
相关产品推荐

