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!
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')
Since the match construct doesn't use set equality to compare sets,
you will need to use a guard to do it explicitly:
a = {1,2,3}
match a:
case _ if a == set([1,2,3]):
print('matched')
It's unintutive that sets aren't compared with set equality by default.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With