如何创建一个带有区间作为case的switch case?

13

我想创建一个开关/情况,其中情况可以具有区间作为条件,例如:

switch = {
    1..<21: do one stuff,
    21...31: do another
}

我该如何达到这个结果?


如果 x 在 1 到 20 之间,则执行 ...;如果 x 在 21 到 30 之间,则执行 ... - olinox14
1
可能是Python中switch语句的替代方案?的重复问题。 - milanbalazs
1
@olinox14 可以工作。但是如果代码发展到支持多个范围条件,那么我认为我正在寻找的 switch case 会更好看。 - gabrielrf97
3个回答

阿里云服务器只需要99元/年,新老用户同享,点击查看详情
27

在Python 3.10中引入了显式的match语句。虽然它不支持直接的包含检查,因此我们将利用guard特性:

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用作键:

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}
其余部分的操作方式相同。
这两个选项的区别在于第一个选项节省了内存,但失去了dict的时间效率(因为需要检查所有键),而第二个选项将保持dict的O(1)查找,代价是占用更多的内存(所有范围的内容)。根据你的应用程序,可以在它们之间选择,一般规则如下: - 少量长范围 - 第一个选项 - 多量短范围 - 第二个选项 - 介于两者之间 - 找到最适合你的情况的解决方案。

你可以只写 case <0 吗? - theonlygusti
@theonlygusti,很难理解你的意思。 - Tomerikoo

1
在Python 3.10中,使用match特性可以检查特定范围内的数字。以下是一个示例:

Python 3.10中,使用match功能,您还可以检查特定范围内的检查号码。这里是我如何做到的示例:

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

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")

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,