为什么在范围值所需的条件语句中调用变量两次?

时间:2018-04-10 07:47:21

标签: python python-2.7

所以,我解决了我的代码问题,其中下面的代码最初没有工作,但我想解释为什么我的原始代码没有按预期工作。如果我指定变量' grade'一旦进入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)

3 个答案:

答案 0 :(得分:5)

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

这是因为在表达式结构<left> and <right>中,leftright都是始终是独立的表达式。表达式可以基于表达式上的表达式构建,但计算机编程语言不仅可以重用left表达式中right表达式的一部分。

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

或者你可以使用不同的表达形式。你可以使用chained comparison expression; Python允许您将<foo> <comparison1> <shared> and <shared> <comparison2> <bar>形式的任何表达式折叠为<foo> <comparison1> <shared> <comparison2> <bar>,而shared表达式只会执行一次。

所以如果你转过来

grade >= 80 and grade <= 89

80 <= grade and grade <= 89

你可以用

替换它
80 <= grade <= 89

但是,请注意前面的测试已经处理grade > 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)]

答案 1 :(得分:1)

如你所知,你不能做像

这样的事情
a <= 10 and >= 20

python 无法明白and适用于a。这是无效的语法,因为and>=都是运算符。

你可以简单地用链式比较来做到这一点:

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"

(或者在你的情况下,有分工和转换)

答案 2 :(得分:1)

虽然如果大声朗读,下面这行可能听起来像一个英文句子,但它只是不正确的python语法:

elif grade >= 80 and <= 89:

原因是and是一个二元运算符,它带有两个完整的表达式,一个在左边,一个在右边。并且<= 89不是一个完整的表达。

所以你的更正版本有效:

elif grade >= 80 and grade <= 89:

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

elif 80 <= grade <= 89: