Python结构模式匹配 - 匹配集合/不可变集合

3
我一直在试玩Python 3.10中的结构模式匹配,但无法弄清如何使其匹配一个集合。例如,我尝试过以下代码:
a = {1,2,3}

match a:
    case set(1,2,3):
        print('matched')

我尝试过以下方法:

a = {1,2,3}

match a:
    case set([1,2,3]):
        print('matched')

除此之外:

a = {1,2,3}

match a:
    case [1,2,3] if isinstance(a, set):
        print('matched')

我猜应该有一种方法可以做到这一点,因为我们可以匹配其他对象,但我不知道正确的语法是什么,也想不到还有什么尝试的办法。任何帮助将不胜感激!谢谢!


我认为在集合中使用SPM没有意义。如果你写case {a, b, c}:,它怎么知道每个值应该赋给哪个变量呢?因为集合没有任何顺序。 - undefined
我还发现,我也无法匹配以元组或冻结集合作为键的字典。似乎能够匹配具有元组或冻结集合作为键的字典会很有帮助,但也许这超出了SPM的本意。 - undefined
你似乎在试图将这个用作“switch/case”。这并不是预期的使用方式。 - undefined
我肯定是的 :) 我猜我的理解是这个意思是将switch / case + pattern matching的好处融合在一起。也许我完全错了吗?看起来我可以在列表或字典键中匹配特定字符串,以及数字的特定值,等等...甚至匹配自定义类之间的相等性也可以。如果我们不能使用特定值匹配内置类型,我对教程展示如何匹配具有特定值的自定义类感到惊讶。 - undefined
它是为了模式匹配而设计的(这在功能名称中就明确表示了)。将其用于值匹配,如switch/case,只是一种退化情况,当模式中没有变量时。但它仍然需要类型支持带有变量赋值的模式匹配。 - undefined
显示剩余2条评论
2个回答

5

这并不是结构模式匹配的正确使用方式;你所匹配的模式更在于而非结构。因此,我认为你会发现等价的if语句形式更易读:

if a == {1, 2, 3}:
    print('matched')

有关这一点...

Python 3.10没有针对匹配集的语法支持。它仅为序列和映射提供了专用的“显示”语法。我认为我们曾经考虑过这个问题,但最终放弃了,因为它并不是非常有用或直观(而且很容易在后续版本中添加它)。

幸运的是,可以使用限定(或“点”)名称通过相等性来匹配任何值。如果你需要将集合作为较大模式或match块的一部分进行匹配,那么这可能是最好的方法:

class Constants:
    SET_123 = {1, 2, 3}

match a:
    case Constants.SET_123:
        print('matched')

如果你只想匹配集合(而不是例如 frozenset),它也可以与类模式相结合使用:

match a:
    case set(Constants.SET_123):
        print('matched')

2

由于match结构不使用集合等式来比较集合,所以您需要使用守卫显式地进行比较:

a = {1,2,3}

match a:
    case _ if a == set([1,2,3]): 
        print('matched')

默认情况下,使用集合相等性不直观。


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