133

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.

Community
  • 1
  • 1
Uyghur Lives Matter
  • 18,820
  • 42
  • 108
  • 144
  • 2
    @AshwiniChaudhary: [That simply isn't true](https://docs.python.org/2/library/constants.html). True and False are both singletons. – Kevin Dec 03 '14 at 16:37
  • 1
    @AshwiniChaudhary `True` and `False` are singletons. The `bool` constructor will return either `True` or `False` by identity, so you cannot create a boolean value that won't compare equal to either `True` or `False` using `is`. – Ferdinand Beyer Dec 03 '14 at 16:40
  • @AshwiniChaudhary see also this : https://hg.python.org/cpython/rev/01a7e66525c2/ – bruno desthuilliers Dec 03 '14 at 16:41
  • 2
    Thanks guys, found the actual source as well. PEP 285 – Ashwini Chaudhary Dec 03 '14 at 16:51
  • 1
    PEP 285 might say that True and False are singletons, but they're not. At least not in the sense that "singleton" means everywhere else in Python documentation: classes that only ever return one instance. True and False aren't classes, they're constants. PEP 285 probably calls them "singletons" in the sense that just as there are never "two different copies" of an object of a singleton class, there are analogously never "two different copies" of True or of False. PEP 285 also falsely claims "None" is a singleton. It's not, it's also a constant, and sole member of the NoneType singleton class. – Marcel Besixdouze Nov 16 '21 at 20:02
  • @MarcelBesixdouze I think it is meant in the sense of the underlying implementation, i.e. there's only one `PyObject*` for `True` and one for `False`, same for `None` and integers below 257 – BETSCH May 24 '23 at 12:06

7 Answers7

114

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.

Uyghur Lives Matter
  • 18,820
  • 42
  • 108
  • 144
Ferdinand Beyer
  • 64,979
  • 15
  • 154
  • 145
  • 7
    This is wrong for very widely libraries such as numpy, which have their own version of boolean values. – Kuhlambo Dec 18 '17 at 16:20
  • 22
    @pindakaas: No, this is not "wrong". This here is an answer to the question "If you want to determine whether a value is exactly True (not just a true-like value)". The argument that some libraries such as numpy come with their own "true-like" types does not hold here! – Ferdinand Beyer Dec 22 '17 at 11:16
  • Does this contradict this answer? https://stackoverflow.com/questions/13650293/understanding-pythons-is-operator – DtechNet Aug 12 '19 at 16:56
  • "As a rule of thumb, you should always use is with the built-in constants True, False and None." If you do that, please document it well. Python generally assumes duck typing. If your function acts differently on `True` and other truthy values, and this is not documented, people that use the function might get *very* confused – tbrugere Jul 15 '21 at 18:18
  • 4
    This answer is wrong. You should **absolutely not** be using `is` with `True` and `False`. It is explicitly forbidden by PEP 8. You can check for *subtype* with `isinstance` if you mean to, and then check the truthiness using the implicit call to `__bool__` like so: `if x`. – Neil G Sep 09 '21 at 13:56
  • @NeilG Hi, check the pylint typer which lints against PEP8 standards, if you type if Flag == True instead of if Flag is True. Pylint will raise the following error. sentiment_analyzer.py:221:11: C0121: Comparison to True should be just 'expr' (singleton-comparison) – m.mashaly Sep 13 '21 at 15:57
  • @m.mashaly Both of those are nearly always wrong, which is what the error message explains: You should type `if flag`. This is what PEP 8 explains. – Neil G Sep 13 '21 at 17:01
  • 1
    @NeilG, I believe you are right, thanks for the clarification, the error message is deleted after replacing is with '==', and Is keyword is faster than '=='. – m.mashaly Sep 13 '21 at 18:33
  • 3
    Relevant links: https://www.python.org/dev/peps/pep-0008/#programming-recommendations. https://switowski.com/blog/checking-for-true-or-false – m.mashaly Sep 13 '21 at 18:34
  • Super weird to see all the support for this answer - this is blatantly incorrect, despite the efforts by some in the comments. PEP-8 states that, not only is this wrong, but it's explicitly worse than using `==` (which it also says is wrong). The `is` operator is for identity comparison. `True` and `False` are not even singletons (they are "flyweight" objects), so their identity only incidentally works in the context of `True is True`. Visit https://peps.python.org/pep-0008/#programming-recommendations and search the page for `Worse:` before wasting the bytes to argue with these facts. – orokusaki Dec 21 '22 at 20:25
48

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_
kadee
  • 8,067
  • 1
  • 39
  • 31
  • 15
    On the contrary, if you want to know whether the object is Python's actual built-in `True` object, `is True` is still the way to go. NumPy boolean array scalars are not the built-in `True` object, no matter whether they pretend to be, and they have critical implementation and behavioral differences from real booleans. – user2357112 Apr 26 '17 at 00:05
  • 5
    I actually agree with you: I personally prefer `is True` and use it wherever I can. But I was surprised it didn't work with numpy / pandas and thought it useful to share here. – kadee May 07 '17 at 11:18
  • Note even if you create a numpy array from Python bools, you is True will evaluate to False, so: `np.array([True])[0] is True` Out[3]: False `np.array([True])[0] == True` Out[4]: True – Ric Hard Aug 15 '18 at 12:11
  • 1
    Very good point. Can you elaborate why this has been chosen to be so different from the rest of Pyhton? This clashes quite dramatically with the accepted answer's rule of thumb: _As a rule of thumb, you should always use `is` with the built-in constants `True`, `False` and `None`._ – Matthias Arras Oct 28 '19 at 14:55
  • See [this answer](https://stackoverflow.com/a/18922572/1551810): "Space and speed. Numpy stores things in compact arrays; if it can fit a boolean into a single byte it'll try. You can't easily do this with Python objects, as you have to store references which slows calculations down significantly." – kadee Oct 30 '19 at 10:05
  • The accepted answer's rule of thumb is at the least controversial: [PEP8](http://www.python.org/dev/peps/pep-0008/#programming-recommendations) explicitly says to use neither `==` nor `is` (which is considered even worse) to compare boolean values. – kadee Oct 30 '19 at 10:06
  • 1
    @kadee That rule applies when you know for sure that the variable in question is a `boolean`. If you don't know the type and you still want to make sure it is python's `True`, I think `if x is True` makes total sense. – Jay Dadhania Jul 15 '21 at 18:11
25

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 ?

bruno desthuilliers
  • 75,974
  • 6
  • 88
  • 118
  • 1
    FWIW : all occurrences of 'if x == True' have been replaced by 'if x is True' in (C)Python 2.6, cf https://hg.python.org/cpython/rev/01a7e66525c2/ - I assume this answers your question. Note that it's _still_ considered unpythonic to explicitely test against `True` or `False' without a good reason ;) – bruno desthuilliers Dec 03 '14 at 16:45
  • If I'm writing an API to drive an instrument, I want to make sure that methods only accept and work with intuitive parameters. `enable_autodestruction(True|False)` makes sense and is clear. It doesn't make any sense to support `enable_autodestruction("123" | [ ])` and that happens if you do not use `is True|False`. – Guimoute Nov 08 '18 at 15:34
  • 3
    @brunodesthuilliers no it wasn't. That's replacing `== None` with `is None`. I don't see the word "True" anywhere in that diff. – Boris Verkhovskiy Jan 07 '20 at 16:50
  • @boris I'm afraid you're right and I obviously need a new pair of glasses. Thanks for correcting me. – bruno desthuilliers Jan 07 '20 at 20:13
  • 1
    @Boris They also replaced `== False` with `is False`, so I would say that you're wrong https://hg.python.org/cpython/rev/01a7e66525c2/#l11.8 – ruohola Sep 25 '20 at 13:48
  • @ruohola that's one instance and that's pretty clearly a mistake. – Boris Verkhovskiy Sep 25 '20 at 15:14
  • @Boris I really wouldn't say so, if you check the repository at that time, it didn't really have many `== True` style checks at all, so there obviously wasn't a need to change many of them. Check for yourself if you don't believe: `hg clone https://hg.python.org/cpython/ --rev 01a7e66525c && cd cpython && hg log --limit=1 && grep --extended --recursive '[!=]= (True|False)' .`. Spoiler: the grep shows a total of 3 results; one of them is in a comment and one of them is in a string, so only one actual usage was left behind (in `Lib/wsgired/validate.py`). – ruohola Sep 26 '20 at 18:54
  • it didn't really have many `== True` style checks because `if x == True` is useless, you can just do `if x` – Boris Verkhovskiy Sep 27 '20 at 13:21
  • 1
    I'm new to Python so I may be offbase, but with dynamic typing my fear is that with a condition ```if flag:``` what if someone sends ```flag='false'```? Or ```flag=EnumValue.ABC```? How do you ever restrict value to True and False with dynamic typing? Without proliferating a raft of direct checks for that throughout the code? Isn't it "Pythonic" that "adults" are free to do anything they feel like and there's no telling what they'll do? – RomnieEE Nov 19 '20 at 23:09
10

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

acushner
  • 9,595
  • 1
  • 34
  • 34
5

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.

  1. 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)
  2. 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()
tbrugere
  • 755
  • 7
  • 17
  • (Python 3.9) Using `is` with a number like `elif foo is 1` will raise a warning: `1: SyntaxWarning: "is" with a literal. Did you mean "=="?`. `is` should be used strictly for identity (memory address) check and not for equality (type+value) check. – Jay Dadhania Jul 15 '21 at 17:53
  • @JayDadhania I didn't know about that, I'll integrate it in the answer. What about `is True`? does it also raise a warning? – tbrugere Jul 15 '21 at 18:03
  • 1
    No, `foo is True` is perfectly legal. But if you know for sure that `foo` is of type boolean, you should just use `if foo:`. – Jay Dadhania Jul 15 '21 at 18:22
2

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.

Mark Ransom
  • 299,747
  • 42
  • 398
  • 622
0

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.

Kevin
  • 28,963
  • 9
  • 62
  • 81