【问题标题】:Why is calling a variable twice in a conditional statement necessary for a ranged value?为什么在范围值所需的条件语句中调用变量两次?
【发布时间】:2018-04-10 07:47:21
【问题描述】:

所以,我解决了我的代码问题,即下面的代码最初不能正常工作,但我想解释一下为什么我的原始代码不能按预期工作。如果我在 if/elif/else 部分中指定了一次变量“等级”并将“和”运算符设置为我需要它工作的参数,不应该将等级与两者进行比较而不必使用它两次?

这是无效的代码

#  if and elif statements for calculating grade score letters
def grade_converter(grade):
    if grade >= 90 :
        return "A"
    elif grade >= 80 and <= 89:
        return "B"
    elif grade >= 70 and <= 79:
        return "C"
    elif grade >= 65 and <= 69:
        return "D"
    else:
        return "F"

# This should print an "A"      
print grade_converter(92)

# This should print a "C"
print grade_converter(70)

# This should print an "F"
print grade_converter(61)

这是我的解决方法

#  if and elif statements for calculating grade score letters
def grade_converter(grade):
    if grade >= 90 :
        return "A"
    elif grade >= 80 and grade <= 89:
        return "B"
    elif grade >= 70 and grade <= 79:
        return "C"
    elif grade >= 65 and grade <= 69:
        return "D"
    else:
        return "F"

# This should print an "A"      
print grade_converter(92)

# This should print a "C"
print grade_converter(70)

# This should print an "F"
print grade_converter(61)

【问题讨论】:

  • 是的,这是无效的语法。但是你可以使用65 &lt;= grade &lt;= 69(链式操作符)会好很多
  • 计算机语言不是英语。人类很擅长猜测复合句中重复的主题,而计算机则不然。您总是明确地在逻辑运算符的两侧说明您要测试的内容。

标签: python python-2.7


【解决方案1】:

计算机语言是不是英语。人类很擅长猜测复合句中重复的主题,而计算机则不然。您总是明确地在逻辑运算符的两侧说明您要测试的内容。

这是因为在表达式结构 &lt;left&gt; and &lt;right&gt; 中,leftright 都是始终独立的表达式。表达式可以建立在表达式上的表达式之上,但计算机编程语言不仅会在 right 表达式中重用(部分)left 表达式。

所以是的,您必须再次明确命名grade

或者你可以使用不同的表达形式。你可以使用chained comparison expression; Python 允许您将&lt;foo&gt; &lt;comparison1&gt; &lt;shared&gt; and &lt;shared&gt; &lt;comparison2&gt; &lt;bar&gt; 形式的任何表达式折叠成&lt;foo&gt; &lt;comparison1&gt; &lt;shared&gt; &lt;comparison2&gt; &lt;bar&gt;,并且shared 表达式将只执行一次。

如果你转身

grade >= 80 and grade <= 89

进入

80 <= grade and grade <= 89

你可以替换成

80 <= grade <= 89

但是,请注意前面的测试已经处理了grade &gt; 89 的情况,您可以放心地放弃上限测试:

def grade_converter(grade):
    if grade >= 90:
        return "A"
    elif grade >= 80:
        return "B"
    elif grade >= 70:
        return "C"
    elif grade >= 65:
        return "D"
    else:
        return "F"

最后但同样重要的是,您可以使用计算机科学技巧。您可以使用bisection,而不是一个一个地单独测试每个年级段;当您的选项排序时,这总是有效的。

不是从最高值开始,而是从中间开始;将可能性分为 2。从那里开始,您不断将可能性减半,直到您拥有合适的年级。这意味着您最多只需要针对 N 种可能性进行 Log(N) 测试,而从最高年级开始最多需要 N 次测试。对于 5 次测试,差别不大(平均 1.6 步,对比 5 步),但是当 N 变得非常大时,您会很快注意到差异;如果您有 100 万个选项,您可以在 14 步内找到匹配选项,保证。

Python 库在bisect module 中包含一个优化的实现:

import bisect

def grade_converter(grade):
    grades = ['F', 'D', 'C', 'B', 'A']
    limits = [65, 70, 80, 90]
    return grades[bisect.bisect(limits, grade)]

【讨论】:

    【解决方案2】:

    正如你所说,你不能做类似的事情

    a <= 10 and >= 20
    

    python 不能理解and 适用于a。这是无效的语法,因为and&gt;= 都是运算符。

    您可以通过链式比较简单地做到这一点:

    def grade_converter(grade):
        if grade >= 90 :
            return "A"
        elif 80 <= grade <= 89:
            return "B"
        elif 70 <= grade <= 79:
            return "C"
        elif 65 <= grade <= 69:
            return "D"
        else:
            return "F"
    

    (或者在你的情况下,带有除法和转换)

    【讨论】:

    • python 有类似 ruby​​ 范围的东西吗?在 ruby​​ 中,我们可以做 case grade when 80..89
    • 你可以使用in range(80,90),但这会创建一个范围对象,不是很好。
    【解决方案3】:

    虽然下面这行在大声朗读时听起来像是一个英文句子,但它根本不是正确的 Python 语法:

    elif grade >= 80 and <= 89:
    

    原因是and 是一个二元运算符,它接受两个完整的表达式,一个在左边,一个在右边。而&lt;= 89 不是一个完整的表达式。

    所以您的更正版本有效:

    elif grade >= 80 and grade <= 89:
    

    但实际上 Python 也允许以下语法:

    elif 80 <= grade <= 89:
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2011-07-28
      • 1970-01-01
      • 1970-01-01
      • 2020-11-09
      • 1970-01-01
      • 2012-11-23
      相关资源
      最近更新 更多