Why is it that I "cannot use assignment expressions with comparison" in Python?

Question:

In the examples below x is assigned using the walrus operator and is then printed.

mystring = "hello, world"


#if 1
if x := mystring == "hello, world":
    print(x)

#if 2
if x := (mystring == "hello, world"):
    print(x)

#if 3
if (x := mystring) == "hello, world":
    print(x)

#if 4
if "hello, world" in (x := mystring):
    print(x)

The Output:

True
True
hello, world
hello, world

I believe that I understand how each of these if statements works…

verbosely:

  1. #if 1 and #if 2 are the same thing where the string comparison == returns True, and that value is reassigned to x.

  2. #if 3 assigns mystring as x before checking the truth of this equal to "hello, world".

  3. #if 4assigns mystring as x then checks if "hello, world" is in this string.

So

What about this final #if 5 is ambiguous to Python such that it gives a Syntax Error?

#if 5
if "hello, world" in x := mystring:
    print(x)
SyntaxError: cannot use assignment expressions with comparison

Is this related to PEP 572 Exceptional Cases:

Unparenthesized assignment expressions are prohibited at the top level of an expression statement.

there is no syntactic position where both are valid.

In reality I am looping through the pathlib Path.iterdir() generator object that yields strings with .stem. This does not change the result:

for file in folder.iterdir():
    x := file.stem == "mystring":
        print(x)
Asked By: GazYah

||

Answers:

in and other comparison operators have a higher precedence than :=. So when you write

if "hello, world" in x := mystring:

it means:

if ("hello, world" in x) := mystring:

which is invalid as it tries to assign to "hello, world" in x. To get it you work you need to use parentheses:

if "hello, world" in (x := mystring):
Answered By: interjay