Python ≥ 3.10 中是否有一种方法可以匹配不等式?

41
Python 3.10 中的新结构化模式匹配功能非常实用。是否可以使用此语句来匹配不等式?原型示例:
match a:
    case < 42:
        print('Less')
    case == 42:
        print('The answer')
    case > 42:
        print('Greater')

7
个人而言,当匹配(不)相等性时,我会使用简单的 if elif else 语句,而不是结构模式。 - Krachtwerk
3个回答

52
你可以使用 guards
match a:
    case _ if a < 42:
        print('Less')
    case _ if a == 42:
        print('The answer')
    case _ if a > 42:
        print('Greater')

另一种没有守卫的选项,使用纯模式匹配:

match [a < 42, a == 42]:
    case [True, False]:
        print('Less')
    case [_, True]:
        print('The answer')
    case [False, False]:
        print('Greater')

14
在第一个例子中,我更愿意使用旧的if/elif语句,因为在我看来它更容易阅读。 - rotten
1
对于第一个 case,似乎 case [True, _]: 也可以工作,并且与您第二个 case 中的模式一致。或者,如果您想要使一致性另一种方式,可以将第二个 case 设为 case [False, True]: - Dennis Williamson
2
如果第一个基本上只是一个带有更多步骤的if-elif,那还有什么意义呢? - wjandrea
@wjandrea 的 match-case 设计看起来很糟糕:/ 应该允许 match a: case < 42 - theonlygusti
1
@theonlygusti 嗯,说实话,这不是它的设计初衷。它非常注重结构模式匹配。看一下我写的这个回答,match-case 使得解析代码更加简洁。[/a/71151862/4518341] - wjandrea
现在我想起来,第二个也只是一个带有更多步骤的if-elif语句:if a < 42: ... elif a == 42: ... else: ...,因为正如@Dennis所说的那样,"case [True, _]:也可以工作"。 - undefined

8
在这个例子中,使用老式的if-elif更简单,即使这意味着重复变量名。
if a < 42:
    print('Less')
elif a == 42:
    print('The answer')
elif a > 42:
    print('Greater')

附言:像Thomas Sollie的回答中使用枚举和比较函数对于增加程序结构是有好处的,但对于基本脚本等来说似乎有些过度设计。

谈到代码风格,避免使用魔法数字:如果你的代码中所有三个42代表同一件事,请给它一个名称,例如:

the_answer = 42
if a < the_answer:
...

5

一个匹配-情况语句本质上是为了匹配相等性而设计的(因此有"match"一词)。在您的原型示例中,您可以通过使用if语句进行匹配(正如其他答案所提出的),但现在您实际上只是匹配True和False,这似乎多余。

其他语言解决此问题的一种方式是使用枚举进行比较:

from enum import Enum


class Ordering(Enum):
    LESS = 1
    EQUAL = 2
    GREATER = 3


def compare(a, b):
    if a < b:
        return Ordering.LESS
    elif a == b:
        return Ordering.EQUAL
    elif a > b:
        return Ordering.GREATER


match compare(a, 42):
    case Ordering.LESS:
        print("Less")
    case Ordering.EQUAL:
        print("The answer")
    case Ordering.GREATER:
        print("Greater")

1
离题了,但是对于其他数字类型来说,该枚举是不完整的。如果数字可以是浮点数,它们可能是NaN,它永远不会比较小、相等或大,只有不相等。而且,假设你可能有一个第三方类型,它不会比较小、相等、大或不相等。所以我可能会添加一个NOT_ORDERABLE成员,或者让compare()抛出一个TypeError - wjandrea
2
在那种情况下,我很难找到使用case语句的理由,因为你可以简单地使用if/elif。这样做只需要一半的代码行数,并且更容易阅读。 - Marcel Wilson

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