[Tutor] Strange results when using not operation.

Alan Gauld alan.gauld at yahoo.co.uk
Fri Apr 21 14:45:15 EDT 2023


On 21/04/2023 15:26, Magnus Myrefors via Tutor wrote:
> Hello !
> 
> I am currently Reading a ”Beginning Python” book, and when 
> I did some tests with the not operation in the IDLE python 
> Shell I saw som strange results. When I typed  


 ’ not”A”  == False ’

> the result was ’True’ and when I typed 

’ not”A” == True ’ the result was ’True’ again.

It would help if you actually copy/pasted the actual code and output.
Above I see single quotes around the code, I assume you did not type
those at the Python prompt?

> I got similar results when I typed ’ not(2) == False ’ 
> and   ’ not(2) == True ’  which both gave the result ’True’ . 

> When I put the whole left side in paranthesis like this: 

’ (not”A”) == False’ and

’ (not”A”) == True ’

> the results were different.


The answer to this seemingly weird behaviour lies in how
Python performs the equality comparison. The relevant part
of the language reference says:

"""The default behavior for equality comparison (== and !=) is based on
the identity of the objects. Hence, equality comparison of instances
with the same identity results in equality, and equality comparison of
instances with different identities results in inequality. A motivation
for this default behavior is the desire that all objects should be
reflexive (i.e. x is y implies x == y)."""


Here is an interactive session including your examples plus a
few more along with my commentary:

Python 3.10.4 (v3.10.4:9d38120e33, Mar 23 2022, 17:29:05) [Clang 13.0.0
(clang-1300.0.29.30)] on darwin
Type "help", "copyright", "credits" or "license" for more information.
>>> not "A" == False
True
>>> not "A" == True
True

Python reads these as:

not("A" == False) and

not("A" == True")

So lets look at the parens:

>>> ("A" == False)
False
>>> ("A" == True)
False

So both sets of parens are false because the string "A"
is not equal to either of the boolean values. The operator
uses an ID comparison. And the string has a different
identity to the booleans.

>>> not "A"
False
>>> (not "A") == False
True
>>> (not "A") == True
False

By putting the parens around the left side you evaluate not "A" first
resulting in a boolean value(False in this case) and then compare that
boolean value to the literal booleans. Thus you get a differrent result
since False == false is indeed True and False == True is indeed False.

>>> not(2) == False
True
>>> not(2) == True
True

The same applies here. Python sees this as:

not ((2) == False)
and
not ((2) == True)

and 2 has a different ID to both True and False so both parens return
False and their negations return True, which is what you saw.

Now the language reference goes on to describe cases where the behaviour
has been changed from the default for some types so ID comparisons are
not always used. Here is the link so you can study it all in detail.

https://docs.python.org/3/reference/expressions.html#value-comparisons

It may take you a few read throughs!

-- 
Alan G
Author of the Learn to Program web site
http://www.alan-g.me.uk/
http://www.amazon.com/author/alan_gauld
Follow my photo-blog on Flickr at:
http://www.flickr.com/photos/alangauldphotos





More information about the Tutor mailing list