Parentheses in Python Conditionals

Question:

I have a simple question regarding the use of parentheses in Python’s conditional statements.

The following two snippets work just the same but I wonder if this is only true because of its simplicity:

>>> import os, socket
>>> if ((socket.gethostname() == "bristle") or (socket.gethostname() == "rete")):
...     DEBUG = False
... else:
...     DEBUG = True
... 
>>> DEBUG

and now without parentheses

>>> import os, socket
>>> if socket.gethostname() == "bristle" or socket.gethostname() == "rete":
...     DEBUG = False
... else:
...     DEBUG = True
... 
>>> DEBUG

Could anyone help shed some light on this? Are there any cases where I should definitely use them?

Asked By: Ben Keating

||

Answers:

The parentheses are redundant in this case. Comparison has a higher precedence than Boolean operators, so the comparisons will always be performed first regardless of the parentheses.

That said, a guideline I once saw (perhaps in Practical C Programming) said something like this:

  1. Multiplication and division first
  2. Addition and subtraction next
  3. Parentheses around everything else

(Yes, IIRC they left out exponentiation!)

The idea being that the precedence rules are arcane enough that nobody should be expected to remember them all, neither the original programmer nor the maintenance programmer reading the code, so it is better to make it explicit. Essentially the parentheses serve both to communicate the intent to the compiler and as documentation for the next schmoe who has to work on it.

I believe in Python those two statements will generate the same bytecode so you’re not even losing any efficiency.

Answered By: kindall

The parentheses just force an order of operations. If you had an additional part in your conditional, such as an and, it would be advisable to use parentheses to indicate which or that and paired with.

if (socket.gethostname() == "bristle" or socket.gethostname() == "rete") and var == condition:
    ...

To differentiate from

if socket.gethostname() == "bristle" or (socket.gethostname() == "rete" and var == condition):
    ...
Answered By: James

The other answers that Comparison takes place before Boolean are 100% correct. As an alternative (for situations like what you’ve demonstrated) you can also use this as a way to combine the conditions:

if socket.gethostname() in ('bristle', 'rete'):
  # Something here that operates under the conditions.

That saves you the separate calls to socket.gethostname and makes it easier to add additional possible valid values as your project grows or you have to authorize additional hosts.

Answered By: g.d.d.c

In Python and many other programming languages, parentheses are not required for every expression with multiple operators. This is because operators have a defined precedence. See the table here (Section 5.15) for information on operator precedence in Python.

You can draw an analogy to arithmetic. These expressions are equivalent:

5 * 5 + 3

(5 * 5) + 3

If you mean to add three first, then you need to use the parentheses like this:

5 * (5 + 3)
Answered By: James Thompson

Have a look at the manual. The higher you are up in the list, the operator will be applied later. “or” is above “==” , and therefore, in this particular case the answers are the same. However, for readability, and just to be sure, I would recommend parenthesis.

Answered By: jarondl

I was always thinking that this is part of PEP8, but apparently it’s not. However in all examples you meet in PEPs, code samples and documentation you never see redundant parentheses (there is even such an inspection in PyCharm, for example).

General recommendation is to use parentheses only if it improves readability or you actually want to change the order of expression calculation (such as (a or b) and c).

Do:

  if (first_expr or second_expr) and third_expr:    

  if first_expr or second_expr:

Don’t:

  if ((first_expr or second_expr) and third_expr):    

  if (first_expr):

  if (first_expr or (second_expr and third_expr)):

In your code sample, parentheses are completely redundant, just use if socket.gethostname() == "bristle" or socket.gethostname() == "rete": (in production code, of course, in will be much more readable, but that’s rather off-topic now)

Answered By: The Godfather

I just met a similar question. My conditional statement is

if count1==0 & count2==0 & count3==0:

The first result is True, the second is False, and the third is True. Intuitively, the result for this conditional statement is true. However, it’s false. But the result for the following sentence is correct;

if (count1==0) & (count2==0) & (count3==0): 

I still have not figured out why this happening.

Answered By: lxy