我想创建一个开关/案例,其中案例可以有间隔作为条件,例如:
switch = {
1..<21: do one stuff,
21...31: do another
}
我怎样才能达到这个结果?
在 Python 3.10 中
引入了一个显式的 switch 语句 -match
。 虽然它不支持直接遏制检查,所以我们必须利用防护功能:
number = int(input("num: "))
match number:
case num if 1 <= num < 21:
# do stuff
case num if 21 <= num < 31:
# do other stuff
case _:
# do default
但在这一点上,它引出了一个问题,为什么不只使用if/elif/else
结构......取决于个人品味。
对于早期版本,看起来您已经尝试过,在 Python 中实现switch
结构的明显方法是使用字典。
为了支持间隔,您可以实现自己的dict
类:
class Switch(dict):
def __getitem__(self, item):
for key in self.keys(): # iterate over the intervals
if item in key: # if the argument is in that interval
return super().__getitem__(key) # return its associated value
raise KeyError(item) # if not in any interval, raise KeyError
现在您可以使用range
s 作为键:
switch = Switch({
range(1, 21): 'a',
range(21, 31): 'b'
})
举几个例子:
>>> print(switch[4])
a
>>> print(switch[21])
b
>>> print(switch[0])
KeyError: 0
另一种选择是解压缩范围并单独保存范围的每个数字。像这样:
cases = {range(1, 21): 'a',
range(21, 31): 'b'
}
switch = {num: value for rng, value in cases.items() for num in rng}
其余的相同。
这两个选项之间的区别在于,第一个选项节省了内存,但失去了字典的时间效率(当您检查所有键时(,而第二个选项将以占用更多内存(所有范围的内容一起(为代价来保持字典的O(1)
查找。
根据您的应用,您可以在它们之间进行选择,作为一般规则:
- 几个长距离 - 第一个选择
- 许多短程 - 第二种选择
- 介于两者之间的任何内容 - 为您的案例找到最佳解决方案
如果你真的必须使用switch/case,那么Python中的字典可以帮助你。有没有办法让字典键成为一个范围?
这是我的看法:
def switch_demo(argument):
switcher = {
range(1, 41): "Class 1 (1-40)",
range(41, 50): "Class 2 (41-49)",
range(50, 99): "Class 3 (50-98)",
99: "Class 4 (99)",
100: "Class 5 (100)"
}
for key in switcher:
if type(key) is range and argument in key:
print(switcher[key])
return
elif type(key) is not range and argument == key:
print(switcher[argument])
return
print("Number class not captured")
在具有匹配功能的 Python 3.10 中,您还可以在特定范围内制作支票号码。这是我如何做到的例子:
number: int = 10
match number:
case num if num in range(10, 49):
# do stuff
case num if num in range(50, 100):
# do other stuff
case _:
# do default