I'm trying to use Python 3.10 structural pattern matching in Python shell:
match a:
case (2 - 1):
after entering the second line, it gives me the following error:
File "<stdin>", line 2
case (2 - 1):
^
SyntaxError: imaginary number required in complex literal
NOTE: I know there's no code to execute after the case, I'm doing this in the shell and it throws this error immediately.
ALSO, I'm aware that I can store them as per this answer, but I'd rather do this directly if there is a way.
CodePudding user response:
You're not allowed to compute arbitrary expressions in a pattern. There's just too much room for conflict with other pattern syntax.
For example, there's little point doing 2 - 1 as a pattern. If you had a value stored in a variable x, you might want to match against x - 1:
case x - 1:
...
but consider what case x means:
case x:
...
case x means "match anything and set x equal to the thing matched". It would be extremely confusing for case x and case x - 1 to do such extremely different things.
The error message you got is because there's one special case where addition and subtraction are allowed in a pattern, as part of a complex number "literal":
case 1 2j:
...
An expression like 1 2j or 1-2j is syntactically an addition or subtraction expression, not a single literal, so Python has to allow this specific case of addition or subtraction to allow constant patterns with complex constants. The error message comes from Python expecting the - to be part of a complex constant.
If you want to match against a computed value, use a guard:
case x if x == arbitrary_expression:
...
CodePudding user response:
You are treating the pattern after case as a normal expression with a value, but it is in fact an entirely new syntactical category in Python; it looks like object construction (i.e. some literal, or a call to a constructor), but it is in fact the opposite, a pattern is used to destructure the object you're trying to match.
So, this works:
match x:
case 1:
print('one')
Because the literal 1 means specifically an int with the value of 1. But (2 - 1) is an expression consisting of two literal integers, an operation and parentheses for grouping. Python tries to interpret it as a pattern and the pattern for destructuring a complex number comes closest.
For example:
n = 2 - 1j
match n:
# these parentheses aren't needed, but allowed;
# they're here to show what Python thought you were trying to do
case (2 - 1j):
print('this number')
case complex(real=r, imag=i):
print('some other complex number')
As pointed out in the other answer, you can use a guard if you need to further restrict the value of what you're trying to match:
def try_this(n):
match n:
case int(x) if x == (2 - 1):
print('what I want')
case int(x):
print('some other int')
try_this(1)
try_this(2)
