所以,我解决了下面的代码最初不起作用的代码问题,但我想解释一下为什么我的原始代码没有按预期工作。如果我在 if/elif/else 部分中指定了一次变量"grade"并将"and"运算符设置为我需要让它工作的参数,难道不应该在不使用它两次的情况下将 grade 与两者进行比较吗?
这是不起作用的代码
# 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)
计算机语言不是英语。人类擅长猜测复合句中重复的主语,而计算机则不然。您始终显式声明在逻辑运算符的两端测试的内容。
这是因为在表达式结构<left> and <right>
中,left
和right
始终是独立的表达式。表达式可以基于表达式构建表达式,但计算机编程语言不会只是在right
表达式中重用(部分)left
表达式。
所以是的,你必须再次明确命名grade
。
或者,您可以使用不同的表达式形式。您可以使用链式比较表达式;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"
最后但并非最不重要的一点是,您可以使用计算机科学技巧。与其逐个测试每个等级带,不如使用平分法;当您的选项被排序时,这始终有效。
与其从最高值开始,不如从中间开始;这将可能性划分为2。从那里开始,您不断将可能性减半,直到您获得合适的等级带。这意味着您最多只需要对 N 种可能性进行 Log(N) 测试,而从最高等级开始最多需要 N 次测试。对于 5 个测试,差别不大(平均 1.6 步,与 5 步相比),但是当 N 变得非常大时,您很快就会注意到差异;如果您有 100 万个选项,则保证在不到 14 个步骤内找到匹配的选项。
Python 库在bisect
模块中包含一个优化的实现:
import bisect
def grade_converter(grade):
grades = ['F', 'D', 'C', 'B', 'A']
limits = [65, 70, 80, 90]
return grades[bisect.bisect(limits, grade)]
正如你所指出的,你不能做类似的事情
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"
(或者在您的情况下,除法和转换)
尽管如果大声朗读,以下行听起来可能听起来可以理解为英语句子,但它根本不是正确的python语法:
elif grade >= 80 and <= 89:
原因是and
是一个二元运算符,它采用两个完整的表达式,一个在左边,一个在右边。<= 89
并不是一个完整的表达。
所以你的更正版本有效:
elif grade >= 80 and grade <= 89:
但实际上Python也允许以下语法:
elif 80 <= grade <= 89: