有没有一种方法可以减少此问题的嵌套if / elif语句的数量?

时间:2020-05-23 15:26:26

标签: python python-3.x if-statement conditional-statements

我正在尝试找到两个数字(totMax和totMin)中的最大值,每个数字都是对应的未知值列表(totMax到maxList和totMin到minList),它们的长度相同。我需要将对应于两个数字中最大的列表存储在变量“最高”中,假设两个数字都在20以下。如果只有一个数字满足条件,则将存储该数字的对应列表。存储在totMax中的数字始终大于存储在totMin中的数字。有没有更简洁的方法?

if totMax > 20 and totMin > 20: 
      raise ValueError(f"Both out of range")
    elif totMax <= 20:
      highest = maxList
    elif totMin <= 20:
      highest = minList
    return highest 

3 个答案:

答案 0 :(得分:3)

为什么不使用max()命令:

if totMax > 20 and totMin > 20:
    raise ValueError(f"Both out of range")
else:
    highest=max(totMax,totMin)
    return highest

OR

因为:

totMax中存储的数字始终大于totMin中存储的数字。

if totMax > 20 and totMin > 20:
    raise ValueError(f"Both out of range")
else:
    highest=totMax
    return highest

答案 1 :(得分:3)

由于您要返回一个与另一个值相关联的值,因此我将首先做一个表示该关联性的字典,然后使用max和一个过滤器进行选择:

total_lists = {
    totMin: minList,
    totMax: maxList,
}
return total_lists[max(t for t in total_lists.keys() if t <= 20)]

如果totMintotMax是各个列表中的值的总和,那么我根本不会使用这些变量,而只是使用sum使其更简单:

return max((v for v in (minList, maxList) if sum(v) <= 20), key=sum)

(编辑)哈哈,和其他人一样,我完全想念这里还有另一套价值观。下面将为后代保留原始答案,但请使用相关列表以我要处理的方式进行编辑。有关异常处理的说明,请参见下文。


在一般情况下,我可以通过构建“候选”值(即在所需范围内的值)列表然后返回它们的max来完成此类操作。仅使用两个值似乎有点过大,但是我倾向于认为,只要您拥有多个值,就应该将它们放入集合中。一旦您的值位于过滤列表中,就很容易根据“此列表是否为空”和“此列表的最高元素是什么”来进行推理,而不必编写单独的if / elif检查每个元素:

values = [v for v in (totMax, totMin) if v <= 20]
if not values:
    raise ValueError("Both out of range")
return max(values)

由于在您的情况下,您可以假设totMax始终高于totMin,因此可以假定values已排序,因此可以选择只返回第一个元素,而不是使用max。 (这是一个棘手的问题,因为对于将来依赖于输入列表顺序的代码的编辑来说,这可能并不明显!)

values = [v for v in (totMax, totMin) if v <= 20]
if not values:
    raise ValueError("Both out of range")
return values[0]  # this works because the original values were in descending order

请注意,如果您不愿意为例外提供自定义文本,则可以单线执行此操作:

# raises ValueError: 'max() arg is an empty sequence' if both values > 20
return max(v for v in (totMax, totMin) if v <= 20)

或者您可以在try / except中重写异常,而不是使用if

try:
    return [v for v in (totMax, totMin) if v <= 20][0]
except IndexError:
    raise ValueError("Both out of range")

最终,您选择哪个选项取决于您对界面的要求以及您的风格偏好! (我本人会和max一起使用一线。)

答案 2 :(得分:1)

其他回答者似乎错过了您要求返回的不是要测试的值,而是一个相关列表的要求。我玩了一点,想出了:

if totMax <= 20:
    highest = maxList
elif totMin > 20: 
    raise ValueError(f"Both out of range")
else :
    highest = minList
return highest 

可以进一步调整为:

if totMax <= 20:
    return maxList
if totMin > 20: 
    raise ValueError(f"Both out of range")
else :
    return minList

但是,从维护的角度来看,您的组织更加清晰,并且将需求表达得更加接近英语对需求规范的理解。

我建议对您的代码进行的唯一更改是,最后一个elif可以是简单的else