A bit part of the appeal of pattern matching in other languages is support for destructuring, where you implicitly assign variables to members of a data structure you're performing a match on. For example, in ML-ish pseudocode:
len([]) = 0
len([first|rest]) = 1 + len(rest)
That's a trivial example. The second PEP (pattern matching tutorial) has several other examples:
So, if you use a variable in a pattern, it's an implicit assignment. If you use a literal, it's a value to be matched against.
I agree that the trivial case (a single variable with no conditions) may be confusing before you know what's going on, but I think the alternative, where a single variable is a comparison but multiple variables (or a structure) is an assignment isn't necessarily better.
> A bit part of the appeal of pattern matching in other languages is support for destructuring, where you implicitly assign variables to members of a data structure you're performing a match on
I would clarify that to implicitly introduce variables.
Consider the following:
$ python3
Python 3.8.6 (default, Dec 28 2020, 20:00:05)
[Clang 7.1.0 (tags/RELEASE_710/final)] on darwin
Type "help", "copyright", "credits" or "license" for more information.
>>> def foo(x):
... return ([x for x in [1, 2, 3]], x, (lambda x: x+1)(x), x)
...
>>> foo(42)
([1, 2, 3], 42, 43, 42)
The list comprehension did not assign the variable x to 1, 2 and 3; it introduced a variable called x, but our original (argument) variable is unaffected (since the second result is 42). Likewise, the nested function doesn't assign its argument variable x, it introduces an argument variable x. Whilst this affects that nested function's result (we get 43), it doesn't affect our original variable, since the final result is still 42.
This match syntax seems to be assigning, rather than introducing, which is a shame.