我通常使用Dictionary实现Switch / Case的相等比较。
dict = {0:'zero', 1:'one', 2:'two'};
a=1; res = dict[a]
代替
if a==0 :
res = 'zero'
elif a == 1:
res = 'one'
elif a==2:
res = 'two'
是否存在实施类似方法进行非平等比较的策略?
if score <=10 :
cat = 'A'
elif score >10 and score <=30:
cat = 'B'
elif score >30 and score <=50 :
cat = 'C'
elif score >50 and score <=90 :
cat = 'D'
else:
cat = 'E'
我知道使用<,<=,>,> =可能会很棘手,但有没有任何策略来概括或生成自动语句来说让我们说一个列表
{[10]:'A', [10,30]:'B', [30,50]:'C',[50,90]:'D',[90]:'E'}
和一些标志,如果它是<或<=
是的,有一种策略,但不像人类思维模式那么干净。第一,一些说明:
list
;这是对dict
的无效尝试。钥匙必须是可清洗的;您提供的列表不是有效密钥。也就是说,我将保留查找表的概念,但我们会将其降低到一个较小的共同点,以便易于理解和改变其他考虑因素。
low = [10, 30, 50, 90]
grade = "ABCDE"
for idx, bkpt in enumerate(low):
if score <= low:
exact = (score == low)
break
cat = grade[idx]
exact
是你要求的旗帜。
对于您的特定情况,将分数转换为O(1)时间复杂度等级的有效方法是使用100减去得分除以10作为字符串索引以获得字母等级:
def get_grade(score):
return 'EDDDDCCBBAA'[(100 - score) // 10]
以便:
print(get_grade(100))
print(get_grade(91))
print(get_grade(90))
print(get_grade(50))
print(get_grade(30))
print(get_grade(10))
print(get_grade(0))
输出:
E
E
D
C
B
A
A
bisect
模块可用于此类分类问题。特别是,文档提供了example,它解决了与您非常相似的问题。
以下是适用于您的用例的相同示例。该函数返回两个值:字母等级和bool
标志,表示匹配是否准确。
from bisect import bisect_left
grades = "ABCDE"
breakpoints = [10, 30, 50, 90, 100]
def grade(score):
index = bisect_left(breakpoints, score)
exact = score == breakpoints[index]
grade = grades[index]
return grade, exact
grade(10) # 'A', True
grade(15) # 'B', False
在上面,我假设你的最后一个断点是100
为E
。如果你真的不想要上限,请注意你可以用100
替换math.inf
以保持代码正常工作。
字典可以包含很多值,如果范围不是太宽,您可以通过以编程方式扩展每个范围来创建类似于相等条件的字典:
from collections import defaultdict
ranges = {(0,10):'A', (10,30):'B', (30,50):'C',(50,90):'D'}
valueMap = defaultdict(lambda:'E')
for r,letter in ranges.items():
valueMap.update({ v:letter for v in range(r[0],r[1]) })
valueMap[701] # 'E'
valueMap[7] # 'A'
如果/ elif语句,您也可以从中删除冗余条件,并将其格式化稍微不同。这几乎看起来像一个案例陈述:
if score < 10 : cat = 'A'
elif score < 30 : cat = 'B'
elif score < 50 : cat = 'C'
elif score < 90 : cat = 'D'
else : cat = 'E'
avoir重复得分<你可以定义一个案例函数并使用它与值:
score = 43
case = lambda x: score < x
if case(10): cat = "A"
elif case(30): cat = "B"
elif case(50): cat = "C"
elif case(90): cat = "D"
else : cat = "E"
print (cat) # 'C'
您可以通过创建一个switch函数来概括这一点,该函数返回一个“case”函数,该函数使用通用比较模式应用于测试值:
def switch(value):
def case(check,lessThan=None):
if lessThan is not None:
return (check is None or check <= value) and value < lessThan
if type(value) == type(check): return value == check
if isinstance(value,type(case)): return check(value)
return value in check
return case
此通用版本允许各种组合:
score = 35
case = switch(score)
if case(0,10) : cat = "A"
elif case([10,11,12,13,14,15,16,17,18,19]):
cat = "B"
elif score < 30 : cat = "B"
elif case(30) \
or case(range(31,50)) : cat = 'C'
elif case(50,90) : cat = 'D'
else : cat = "E"
print(cat) # 'C'
当你需要做的就是返回一个值时,还有另一种使用lambda函数的方法:
score = 41
case = lambda x,v: v if score<x else None
cat = case(10,'A') or case(20,'B') or case(30,'C') or case(50,'D') or 'E'
print(cat) # "D"
最后一个也可以使用列表推导和映射表来表达:
mapping = [(10,'A'),(30,'B'),(50,'C'),(90,'D')]
scoreCat = lambda s: next( (L for x,L in mapping if s<x),"E" )
score = 37
cat = scoreCat(score)
print(cat) #"D"
low = [10,30,50,70,90]
gradE = "FEDCBA"
def grade(score):
for i,b in enumerate(low):
#if score < b: # 0--9F,10-29E,30-49D,50-69C,70-89B,90-100A Easy
if score <= b: # 0-10F,11-30E,31-50D,51-70C,71-90B,91-100A Taff
return gradE[i]
else:return gradE[-1]
for score in range(0,101):
print(score,grade(score))