【问题标题】:Structural Pattern Matching Python - Matching a Set / Frozenset结构模式匹配 Python - 匹配集合 / Frozenset
【发布时间】:2021-06-03 20:11:04
【问题描述】:

我一直在使用 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}:,它怎么知道哪个变量应该获取集合中的每个值,因为集合没有任何顺序?
  • 我明白为什么有人肯定会做出这个决定。我可能会建议在可能返回多种类型的情况下,最好使用相同的匹配语句,而不是结合匹配语句和 if 块,但我认为你不应该在正确的代码中包含这些情况。我还看到我无法匹配元组或冻结集也是键的字典。我在想 PEP-634 表明支持所有这些基本类型。也许我只是误解了它在说什么?
  • 我还看到我无法匹配元组或冻结集也是键的字典。能够将带有元组或冻结集的字典作为键匹配似乎会有所帮助,但也许这也超出了 SPM 的含义
  • 您似乎试图将其用作switch/case。这不是预期用途。
  • 我肯定是 :) 我想我的理解是这意味着开关 / 大小写 + 模式匹配的优点都合二为一。也许我完全看错了?似乎我可以匹配列表或字典键中的特定字符串以及数字的特定值等......甚至自定义类之间的匹配相等性也可以。如果我们无法将内置类型与特定值匹配,我很惊讶本教程显示将自定义类与特定值匹配

标签: python structural-pattern-matching


【解决方案1】:

这并不是结构模式匹配的真正用途;您匹配的模式更多的是关于 value 而不是 structure。正因为如此,我想你会发现等价的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')

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

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

    默认情况下不将集合与集合相等性进行比较是不直观的。

    【讨论】:

      猜你喜欢
      • 2021-05-04
      • 2019-09-10
      • 1970-01-01
      • 2018-06-09
      • 1970-01-01
      • 2015-08-10
      • 2023-02-09
      • 1970-01-01
      • 2015-03-14
      相关资源
      最近更新 更多