有没有办法减少这个问题的嵌套if/elif语句的数量?

2024-10-04 11:34:02 发布

您现在位置:Python中文网/ 问答频道 /正文

我试图找到两个数字的最大值(totMax和totMin),每个数字对应一个相同长度的未知值列表(totMax到maxList和totMin到minList)。我需要存储与变量'highest'中两个数字的最大值对应的列表,假设两个数字都小于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 

Tags: and方法列表if数字号码raisevalueerror
3条回答

其他回答者似乎忽略了您的要求,即返回的不是您正在测试的值,而是相关列表。我玩了一会儿,想出了:

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

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

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

因为:

The number stored in totMax with always be higher that the number store in totMin.

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

由于您希望返回一个与另一个相关联的值,因此我首先制作一个dict来表示该关联,然后使用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的一行。)

相关问题 更多 >