【问题标题】:Is there a way of reducing the quantity nested if/elif statements for this problem?有没有办法减少这个问题的嵌套 if/elif 语句的数量?
【发布时间】:2020-09-10 10:27:03
【问题描述】:

我试图找到两个数字(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 

【问题讨论】:

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


【解决方案1】:

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

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

因为:

totMax 中存储的数字总是大于 totMin 中存储的数字。

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

【讨论】:

    【解决方案2】:

    由于您想返回一个与另一个关联的值,我会先创建一个 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 已排序,因此您可以选择只返回第一个元素而不是使用@ 987654334@。 (这有点棘手,因为对于未来的代码编辑器来说,你依赖于输入列表的顺序可能并不明显!)

    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 的单线。)

    【讨论】:

    • 不错。我考虑过使用dict,但没有找到避免使其更复杂/复杂的快速方法。我需要更多地练习理解力。
    【解决方案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

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2016-01-04
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2020-11-17
      • 1970-01-01
      • 2012-01-16
      相关资源
      最近更新 更多