Search code examples
pythonstructural-pattern-matching

Structural Pattern Matching Python - Matching a Set / Frozenset


I've been playing around with Structural Pattern Matching in Python 3.10 and can't figure out how to get it to match a set. For example I've tried:

a = {1,2,3}

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

and I've tried:

a = {1,2,3}

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

As well as:

a = {1,2,3}

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

I'm guessing there is a way to do this since we can match other objects and I'm just missing the correct syntax but I can't think of what else to try. Any help would be appreciated! Thanks!


Solution

  • This isn't really how structural pattern matching is meant to be used; the pattern you're matching is more about value than structure. Because of this, I think you'll find that the equivalent if form is much more readable:

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

    With that said...

    Python 3.10 doesn't have syntactic support for matching sets; it only has dedicated "display" syntax for sequences and mappings. I think we briefly considered this, but ultimately dropped it because wasn't very useful or intuitive (and it's easy enough to add in a later version).

    Fortunately, it's possible to match any value by equality using a qualified (or "dotted") name. If you need to match a set as part of a larger pattern or match block, that's probably the best way to do it:

    class Constants:
        SET_123 = {1, 2, 3}
    
    match a:
        case Constants.SET_123:
            print('matched')
    

    It can also be combined with a class pattern if you only want to match sets (and not, for example, frozensets):

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