Boolean identity == True vs is True
Question:
It is standard convention to use if foo is None
rather than if foo == None
to test if a value is specifically None
.
If you want to determine whether a value is exactly True
(not just a true-like value), is there any reason to use if foo == True
rather than if foo is True
? Does this vary between implementations such as CPython (2.x and 3.x), Jython, PyPy, etc.?
Example: say True
is used as a singleton value that you want to differentiate from the value 'bar'
, or any other true-like value:
if foo is True: # vs foo == True
...
elif foo == 'bar':
...
Is there a case where using if foo is True
would yield different results from if foo == True
?
NOTE: I am aware of Python booleans – if x:, vs if x == True, vs if x is True. However, it only addresses whether if foo
, if foo == True
, or if foo is True
should generally be used to determine whether foo
has a true-like value.
UPDATE: According to PEP 285 § Specification:
The values False and True will be singletons, like None.
Answers:
edit: regarding:
Is there a case where using if foo is True
would yield different results from if foo == True
?
there is a case, and it’s this:
In [24]: 1 is True
Out[24]: False
In [25]: 1 == True
Out[25]: True
additionally, if you’re looking to use a singleton as a sentinel value, you can just create an object:
sentinel_time = object()
def f(snth):
if snth is sentinel_time:
print 'got em!'
f(sentinel_time)
you don’t want to use if var == True:
, you really want if var:
.
imagine you have a list. you don’t care if a list is “True
” or not, you just want to know whether or not it’s empty. so…
l = ['snth']
if l:
print l
check out this post for what evaluates to False
: Evaluation of boolean expressions in Python
is there any reason to use if foo == True rather than if foo is True?”
>>> d = True
>>> d is True
True
>>> d = 1
>>> d is True
False
>>> d == True
True
>>> d = 2
>>> d == True
False
Note that bool
is a subclass of int
, and that True
has the integer value 1
. To answer your question, if you want to check that some variable “is exactly True”, you have to use the identity operator is
. But that’s really not pythonic… May I ask what’s your real use case – IOW : why do you want to make a difference between True
, 1
or any ‘truth’ value ?
If you want to determine whether a value is exactly True (not just a true-like value), is there any reason to use if foo == True rather than if foo is True?
If you want to make sure that foo
really is a boolean and of value True
, use the is
operator.
Otherwise, if the type of foo
implements its own __eq__()
that returns a true-ish value when comparing to True
, you might end up with an unexpected result.
As a rule of thumb, you should always use is
with the built-in constants True
, False
and None
.
Does this vary between implementations such as CPython (2.x and 3.x), Jython, PyPy, etc.?
In theory, is
will be faster than ==
since the latter must honor types’ custom __eq__
implementations, while is
can directly compare object identities (e.g., memory addresses).
I don’t know the source code of the various Python implementations by heart, but I assume that most of them can optimize that by using some internal flags for the existence of magic methods, so I suspect that you won’t notice the speed difference in practice.
Most of the time, you should not care about a detail like this. Either you already know that foo
is a boolean (and you can thus use if foo
), or you know that foo
is something else (in which case there’s no need to test). If you don’t know the types of your variables, you may want to refactor your code.
But if you really need to be sure it is exactly True
and nothing else, use is
. Using ==
will give you 1 == True
.
Here’s a test that allows you to see the difference between the 3 forms of testing for True:
for test in ([], [1], 0, 1, 2):
print repr(test), 'T' if test else 'F', 'T' if test == True else 'F', 'T' if test is True else 'F'
[] F F F
[1] T F F
0 F F F
1 T T F
2 T F F
As you can see there are cases where all of them deliver different results.
Never use is True
in combination with numpy (and derivatives such as pandas):
In[1]: import numpy as np
In[2]: a = np.array([1, 2]).any()
In[4]: a is True
Out[4]: False
In[5]: a == True
Out[5]: True
This was unexpected to me as:
In[3]: a
Out[3]: True
I guess the explanation is given by:
In[6]: type(a)
Out[6]: numpy.bool_
Using foo is True
instead of foo == True
(or just foo
) if is most of the time not what you want.
I have seen foo is True
used for checking that the parameter foo
really was a boolean.
- It contradicts python’s duck-typing philosophy (you should in general not check for types. A function acting differently with
True
than with other truthy values is counter-intuitive for a programmer who assumes duck-typing)
- Even if you want to check for types, it is better to do it explicity like :
def myFunction(foo):
if not isinstance(foo, bool):
raise ValueError("foo should be a boolean")
>>> myFunction(1)
Exception: ValueError "foo should be a boolean"
For several reasons:
- Bool is the only type where the
is
operator will be equivalent to isinstance(a, bool) and a
. The reason for that is the fact that True
and False
are singletons. In other words, this works because of a poorly known feature of python (especially when some tutorials teach you that True
and False
are just aliases for 1
and 0
).
- If you use isinstance and the programmer was not aware that your function did not accept truthy-values, or if they are using
numpy
and forgot to cast their numpy-boolean to a python-boolean, they will know what they did wrong, and will be able to debug.
Compare with
def myFunction(foo):
if foo is True:
doSomething()
else:
doSomethingElse()
In this case, myFunction(1)
not only does not raise an exception, but probably does the opposite of what it was expected to do. This makes for a hard to find bug in case someone was using a numpy boolean for example.
When should you use is True
then ?
EDIT: Please don’t. It’s explicitely advised against by PEP 8 as mentioned in comments on another answer.
EDIT: this is bad practice, starting from 3.9, python raises a warning when you try to use is
to compare with a literal. See @ JayDadhania’s comment below. In conclusion is
should not be used to compare to literals, only to check the equality of memory address.
Just don’t use it. If you need to check for type, use isinstance
.
Old paragraph:
Basically, use it only as a shorthand for isinstance(foo, bool) and foo
The only case I see is when you explicitely want to check if a value is true, and you will also check if the value is another truthy value later on. Examples include:
if foo is True:
doSomething()
elif foo is False:
doSomethingElse()
elif foo is 1: #EDIT: raises a warning, use == 1 instead
doYetSomethingElse()
else:
doSomethingElseEntirely()
It is standard convention to use if foo is None
rather than if foo == None
to test if a value is specifically None
.
If you want to determine whether a value is exactly True
(not just a true-like value), is there any reason to use if foo == True
rather than if foo is True
? Does this vary between implementations such as CPython (2.x and 3.x), Jython, PyPy, etc.?
Example: say True
is used as a singleton value that you want to differentiate from the value 'bar'
, or any other true-like value:
if foo is True: # vs foo == True
...
elif foo == 'bar':
...
Is there a case where using if foo is True
would yield different results from if foo == True
?
NOTE: I am aware of Python booleans – if x:, vs if x == True, vs if x is True. However, it only addresses whether if foo
, if foo == True
, or if foo is True
should generally be used to determine whether foo
has a true-like value.
UPDATE: According to PEP 285 § Specification:
The values False and True will be singletons, like None.
edit: regarding:
Is there a case where using
if foo is True
would yield different results fromif foo == True
?
there is a case, and it’s this:
In [24]: 1 is True
Out[24]: False
In [25]: 1 == True
Out[25]: True
additionally, if you’re looking to use a singleton as a sentinel value, you can just create an object:
sentinel_time = object()
def f(snth):
if snth is sentinel_time:
print 'got em!'
f(sentinel_time)
you don’t want to use if var == True:
, you really want if var:
.
imagine you have a list. you don’t care if a list is “True
” or not, you just want to know whether or not it’s empty. so…
l = ['snth']
if l:
print l
check out this post for what evaluates to False
: Evaluation of boolean expressions in Python
is there any reason to use if foo == True rather than if foo is True?”
>>> d = True
>>> d is True
True
>>> d = 1
>>> d is True
False
>>> d == True
True
>>> d = 2
>>> d == True
False
Note that bool
is a subclass of int
, and that True
has the integer value 1
. To answer your question, if you want to check that some variable “is exactly True”, you have to use the identity operator is
. But that’s really not pythonic… May I ask what’s your real use case – IOW : why do you want to make a difference between True
, 1
or any ‘truth’ value ?
If you want to determine whether a value is exactly True (not just a true-like value), is there any reason to use if foo == True rather than if foo is True?
If you want to make sure that foo
really is a boolean and of value True
, use the is
operator.
Otherwise, if the type of foo
implements its own __eq__()
that returns a true-ish value when comparing to True
, you might end up with an unexpected result.
As a rule of thumb, you should always use is
with the built-in constants True
, False
and None
.
Does this vary between implementations such as CPython (2.x and 3.x), Jython, PyPy, etc.?
In theory, is
will be faster than ==
since the latter must honor types’ custom __eq__
implementations, while is
can directly compare object identities (e.g., memory addresses).
I don’t know the source code of the various Python implementations by heart, but I assume that most of them can optimize that by using some internal flags for the existence of magic methods, so I suspect that you won’t notice the speed difference in practice.
Most of the time, you should not care about a detail like this. Either you already know that foo
is a boolean (and you can thus use if foo
), or you know that foo
is something else (in which case there’s no need to test). If you don’t know the types of your variables, you may want to refactor your code.
But if you really need to be sure it is exactly True
and nothing else, use is
. Using ==
will give you 1 == True
.
Here’s a test that allows you to see the difference between the 3 forms of testing for True:
for test in ([], [1], 0, 1, 2):
print repr(test), 'T' if test else 'F', 'T' if test == True else 'F', 'T' if test is True else 'F'
[] F F F
[1] T F F
0 F F F
1 T T F
2 T F F
As you can see there are cases where all of them deliver different results.
Never use is True
in combination with numpy (and derivatives such as pandas):
In[1]: import numpy as np
In[2]: a = np.array([1, 2]).any()
In[4]: a is True
Out[4]: False
In[5]: a == True
Out[5]: True
This was unexpected to me as:
In[3]: a
Out[3]: True
I guess the explanation is given by:
In[6]: type(a)
Out[6]: numpy.bool_
Using foo is True
instead of foo == True
(or just foo
) if is most of the time not what you want.
I have seen foo is True
used for checking that the parameter foo
really was a boolean.
- It contradicts python’s duck-typing philosophy (you should in general not check for types. A function acting differently with
True
than with other truthy values is counter-intuitive for a programmer who assumes duck-typing) - Even if you want to check for types, it is better to do it explicity like :
def myFunction(foo):
if not isinstance(foo, bool):
raise ValueError("foo should be a boolean")
>>> myFunction(1)
Exception: ValueError "foo should be a boolean"
For several reasons:
- Bool is the only type where the
is
operator will be equivalent toisinstance(a, bool) and a
. The reason for that is the fact thatTrue
andFalse
are singletons. In other words, this works because of a poorly known feature of python (especially when some tutorials teach you thatTrue
andFalse
are just aliases for1
and0
). - If you use isinstance and the programmer was not aware that your function did not accept truthy-values, or if they are using
numpy
and forgot to cast their numpy-boolean to a python-boolean, they will know what they did wrong, and will be able to debug.
Compare with
def myFunction(foo):
if foo is True:
doSomething()
else:
doSomethingElse()
In this case, myFunction(1)
not only does not raise an exception, but probably does the opposite of what it was expected to do. This makes for a hard to find bug in case someone was using a numpy boolean for example.
When should you use is True
then ?
EDIT: Please don’t. It’s explicitely advised against by PEP 8 as mentioned in comments on another answer.
EDIT: this is bad practice, starting from 3.9, python raises a warning when you try to use is
to compare with a literal. See @ JayDadhania’s comment below. In conclusion is
should not be used to compare to literals, only to check the equality of memory address.
Just don’t use it. If you need to check for type, use isinstance
.
Old paragraph:
Basically, use it only as a shorthand for isinstance(foo, bool) and foo
The only case I see is when you explicitely want to check if a value is true, and you will also check if the value is another truthy value later on. Examples include:
if foo is True:
doSomething()
elif foo is False:
doSomethingElse()
elif foo is 1: #EDIT: raises a warning, use == 1 instead
doYetSomethingElse()
else:
doSomethingElseEntirely()