Is there an actual difference between
if statement:
and
if statement == True:
Aside from the first one being shorter, does one have a higher precedence, or is one slower?
EDIT:
I realized this may not have been clear, but statement
is usually statement = True
.
Those are not equal. Python allows you to define if
statements over a large range of elements. You can for instance write:
if []: # is False
pass
if 1425: # is True
pass
if None: # is False
pass
Basically if you write if <expr>
, Python will evaluate the truthness of the expression. This is predefined for numbers (int
, float
, complex
, not being equal to zero), some builtin collections (list
, dict
, not being empty), and you can define a __bool__
or __len__
on an arbitrary object yourself. You can get the truthness of an object by calling bool(..)
on it. For example bool([]) == False
.
Example where if x
is not equal to if x == True
:
For instance:
if 0.1:
pass # will take this branch
else:
pass
will take the if
branch, whereas:
if 0.1 == True:
pass
else:
pass # will take this branch
will not take the if
branch. This is because a number is equal to True
if it is one (1
, 1L
, 1+0j
,...). Whereas bool(x)
for a number is True
if x
is non-zero.
It is also possible to define an object where ==
will raise an exception. Like:
class Foo:
def __eq__(self,other):
raise Exception()
Now calling Foo() == True
will result in:
>>> Foo() == True
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
File "<stdin>", line 3, in __eq__
Exception
It is however not advisable to raise exceptions in the __eq__
function (well I strongly advice against it anyway).
It however holds that: if <expr>:
is equivalent to if bool(<expr>):
.
Given the two are equal, evidently the <expr> == True
will be slower since you do an extra call to __eq__
, etc.
Furthermore it is usually more idiomatic to check if a collection is empty with:
some_list = []
if some_list: # check if the list is empty
pass
This is also more safe since if it possible that some_list
is None
(or another kind of collection), you still check whether it holds at least one element, so changing your mind a bit will not have dramatic impact.
So if you have to write if x == True
, there is usually something weird with the truthness of the x
itself.
As is specified in the documentation (Python-2.x/Python-3.x). There is a way to resolve truthness.
In python-2.x, it is evaluated like (over-simplified version, more "pseudo Python" code to explain how it works):
# Oversimplified (and strictly speaking wrong) to demonstrate bool(..)
# Only to show what happens "behind the curtains"
def bool(x):
if x is False or x is None:
return False
if x == 0 or x == 0.0 or x == 0L or x == 0j:
return False
if x is () or x == [] or x == '' or x == {}:
return False
if hasattr(x,'__nonzero__'):
y = x.__nonzero__()
return y != 0 and y != False
if hasattr(x,'__len__'):
return x.__len__() != 0
return True
and an over-simplified version for python-3.x:
# Oversimplified (and strictly speaking wrong) to demonstrate bool(..)
# Only to show what happens "behind the curtains"
def bool(x):
if x is False or x is None:
return False
if x == 0 or x == 0.0 or x == 0j:
return False
if x is () or x == [] or x == '' or x == {}:
return False
if hasattr(x,'__bool__'):
return x.__bool__() is True
if hasattr(x,'__len__'):
return x.__len__() != 0
return True