With Python 3.11.0a2+, and the following code:
def my_fun(e):
match e:
case (1,):
print("tuple (1,)")
case [1]:
print("list [1]")
case _:
print("I don't understand")
Calling the function with my_fun([1])
prints "tuple (1,)".
Is this behavior correct?
If I explicitly match against tuple((1, ))
instead of (1,)
, it works as expected.
If this is not a bug of the interpreter, what is the reason behind this seemingly weird behavior?
This is documented under Structural Pattern Matching
Like unpacking assignments, tuple and list patterns have exactly the same meaning and actually match arbitrary sequences. Technically, the subject must be a sequence. Therefore, an important exception is that patterns don’t match iterators. Also, to prevent a common mistake, sequence patterns don’t match strings.
and in PEP 635 -- Structural Pattern Matching: Motivation and Rationale
As in iterable unpacking, we do not distinguish between 'tuple' and 'list' notation.
[a, b, c]
,(a, b, c)
anda, b, c
are all equivalent. While this means we have a redundant notation and checking specifically for lists or tuples requires more effort (e.g. caselist([a, b, c]))
, we mimic iterable unpacking as much as possible.