Why does `(not True == False)` work but not `(True == not False)`?

Question

In Python, why would this work,
(not True == False)

but not this?
(True == not False)

Answer

The reason for this is mainly due to the order of operations in Python.

The not operator has a lower precedence than the comparison operators such as ==, !=, <, >, <= and >=.

As a result, in this expression, the == operator will be evaluated first, before the not is evaluated. Because of this, it will try to compare True == not first, which would not work and would cause an error.

Example

# True == False is evaluated first.
# Then the result will be reversed with 'not'.
not True == False # True

# This would not work.
# It will try to evaluate 'True == not' first, which is not valid.
True == not False
29 Likes

I look at it as the not is evaluating the whole Boolean, not just one side.

so not True == False would be looked at as:

  1. not (True == False)
  2. not (False)

answer: True

15 Likes

Exactly correct, but the point of bringing in operator precedence is to explain why
True == not False
… raises a SyntaxError.

1 Like

Assignment is the only time that comes to mind where we can combine operators.

+=, -=, *=, &c.
     == not

Those two operators cannot appear without an operand between them.

2 Likes

Just because it hasn’t been mentioned, the code can be fixed with parentheses:

True == (not False)

And as suggested this is because of the order of operations.

22 Likes

But the below works:

print(True == (not False))

1 Like

Hi,
The solution has … and not (credits >= 120) which is fine. But I wrote … and (credits < 120) which I also think is correct. I try not to tie my brain in NOT’s when I can help it.

7 Likes

I did just that initially without worrying about the Not operator. But later realized the lesson was on the Not operator and that I was expected to use the Not operator. lol

5 Likes

I think using ‘not’ would come in handy when you need to evaluate a static expression. Meaning, (credits >= 120) cannot be changed to something like (credits < 120).

For example: If I was given the following variables below
gpa_ = credits >= 120
credits_ = credits >= 120

and felt that creating more variables or adding more expressions into the code was too inconvenient, then I could use ‘not’ to evaluate each expressions that is false back to true so I can execute the code block below the expression. Here is how I wrote the code:

def graduation_reqs(gpa,credits):
gpa_ = gpa >= 2.0
credits_ = credits >= 120
if (gpa_) and (credits_):
return “You meet the requirements to graduate!”
if not (gpa_) and not (credits_):
return “You do not meet either requirements to graduate!”
if (gpa_) and not (credits_):
return “You do not have enough credits to graduate.”
if not (gpa_) and (credits_):
return “Your GPA is not high enough to graduate.”

13 Likes

@clara05 - Excellently example and much appreciated. I didn’t use the not operator in my solution, which troubled me since I know the lesson was trying to teach me how to use it. Your example really helped me understand how not can be used and why it is useful. My brain is not used to using inverse logic yet.

Thanks. Your example made it clear and make sense why using the not in this exercise

Well, this example helped a lot.
print(“Thank you, Clara!”)

3 Likes

Uma solução que eu “pensei” foi controlar a ordem de avaliação das expressões, garantindo a ordem de execução desejada neste caso.

The solution that I “thought of” was to control the order of evaluation of expressions, ensuring the desired execution order in this case.

True == (not False)