MuhammadOsta
MuhammadOsta

Reputation: 88

Python, effect of parentheses on booleans in print statement

Would you please explain to me why the parentheses affect the output of booleans passed to a print statement?

Example:

print(True and False) or (True or False)
#         False       or      True
# Python 2.7 >>> True
# Python 3.6 >>> False

But when I use parentheses:

print((True and False) or (True or False))
#          False       or      True
# Python 2.7 >>> True
# Python 3.6 >>> True

Does the interpreter in Python 3 only see the first part (the one inside the first parentheses)? if so, why it doesn't throw an error for the rest of the line?

Other examples:

print(True and True) and (True and False)
#          True      and      False
# Python 2.7 >>> False
# Python 3.6 >>> True

print((True and True) and (True and False))
#          True       and      False
# Python 2.7 >>> False
# Python 3.6 >>> False

print(True and True) and not (False or True)
#         True       and not       True
# Python 2.7 >>> False
# Python 3.6 >>> True

print((True and True) and not (False or True))
#         True        and not       True
# Python 2.7 >>> False
# Python 3.6 >>> False

print(False or True) and not (True and True)
#          True      and not       True
# Python 2.7 >>> False
# Python 3.6 >>> True

print((False or True) and not (True and True))
#          True       and not       True
# Python 2.7 >>> False
# Python 3.6 >>> False

UPDATE FROM ANSWERS AND COMMENTS:

my question in BOLD:

In Python3, print is a function. print(True and False) is None, and

print(True and False) or (True or False)

is the same as

None and (True or False)

which is False, as None is false-y in boolean context.

isn't like telling the interpreter to print something or evaluate other stuff? how can this be a valid syntax?

since the first part was evaluated to None then the second evaluation: None and (True or False) shouldn't print anything unless i run it in the shell. for example: running None and (True or False) wouldn't print the result to user if it run in a code editor like SublimeText3 (I don't use any extra plugin or package in sublime, only the build function of the program, and it doesn't print anything unless it's passed to a print statement.)

little gif to demonstrate

Upvotes: 3

Views: 1998

Answers (3)

Thierry Lathuille
Thierry Lathuille

Reputation: 24280

In Python3, print is a function. As all functions who don't have a specific return value, it returns None.

So, what happens when you execute print(True and False) or (True or False) is the following:

True and False gets evaluated, which gives False.

The functionprint() gets called with False as argument. This print(False) first prints "False" to the terminal, then returns the value None.

Now,

None or (True or False)

gets evaluated to True.

If you execute this as part of a script, "False" gets printed, the whole expression gets evaluated to True, and as you don't assign this True to anything, it is just discarded.

If you execute this in the REPL, "False" gets printed, the whole expression gets evaluated to False, and the REPL prints the result of the evaluation, as it would have printed 4 if you had entered 2+2, so you get

>>> print(True and False) or (True or False)
False  # <-- from print
True  # <-- from the REPL, result of the evaluation of the whole expression

There's a little difference if you execute print(True and False) and (True or False). This time, after printing, the expression is

None and (True or False)

As None is falsy in boolean context, Python knows that the result of and will be false (without even needing to evaluate the (True or False) part), and returns None, as it is the first value that allowed it to decide the truthiness of the expression.

If you execute this as part of a script, as before, "False" gets printed, the whole expression gets evaluated to None, and as you don't assign this None to anything, it is just discarded.

If you execute this in the REPL, "False" gets printed, the whole expression gets evaluated to None. As this is the ordinary return value of all functions who return nothing, the REPL doesn't print it unless you explicitely ask it to :

>>> print(True and False) and (True or False)
False  # <-- from print, None doesn't get printed
>>> print(print(True and False) and (True or False))
False  # <-- from the inner print
None   # <-- None gets printed by the outer print 
>>> 

Upvotes: 10

Aran-Fey
Aran-Fey

Reputation: 43276

In python 2, print is a statement. As a result, everything after the print is evaluated as a single expression.

For example,

print(True and False) or (True or False)

is evaluated like

result = (True and False) or (True or False)
print result

But in python 3, print is a function, and only the expression inside the parenthesis is printed:

result = True and False
print(result) or (True or False)

This looks weird, but is valid syntax, because print is a function. It's essentially equivalent to this:

result = True and False
result2 = print(result)
final_result = result2 or (True or False)

In short, it's like python 2 adds an additional pair of parentheses around everything after print.

Upvotes: 1

David
David

Reputation: 433

Print is a statement in Python2 so it doesn't need the parenthesis, while it's a function in Python3 so it does need them.

So Python2 see print(True and False) or (True or False) as a single statement, while Python3 sees print(True and False) as a valid statement in itself and computes that.

Upvotes: 2

Related Questions