1

I have seen it said that, in Python, comparisons with boolean values should be of the form if x:, not if x == True:, and certainly not of the form if x is True:.

>>> 
>>> id(True)
505509720
>>> a = True
>>> id(a)
505509720
>>> random_string_to_reference_a_different_area_of_memory = "Python"
>>> id(True)
505509720
>>>

Playing around with variables and looking at memory locations (see above), it looks to me like there is only one True and one False object, so why shouldn't we do if x is True: (or is it actually fine to do so)?

Also, is there any reason why we shouldn't do if x == True, other than the fact that the == True is unnecessary; if so, would you be able to give me a description in terms of memory?

I personally feel that using is is more appropriate than using ==, since when we are doing a comparison it looks like we are actually looking at whether a variable points to the True or False object. Could anyone give me an explanation of what is best, and why, and how it all works?

jonrsharpe
  • 115,751
  • 26
  • 228
  • 437
Lord Cat
  • 401
  • 4
  • 13
  • Presumably when you say you've *"seen it said"*, you mean https://www.python.org/dev/peps/pep-0008/#programming-recommendations? Also, *"how it all works"* is rather too broad for an SO question. – jonrsharpe Apr 03 '15 at 16:37
  • Just because the id of `True` and `False` *appear* to be consistent, doesn't mean they're guaranteed to be so. – Mark Ransom Apr 03 '15 at 16:39
  • FYI, looking at two object ids without those objects being alive at the same time is kind of pointless. The old one could have been garbage-collected, resulting in the new one re-using its memory location. – ThiefMaster Apr 03 '15 at 16:41
  • @MarkRansom It makes sense for them to be though. I shall see if I can find an answer on the internet. – Lord Cat Apr 03 '15 at 16:42

2 Answers2

5

You shouldn't be using == True or == False either, unless you explicitly need to test against the boolean value (which you almost never don't). The preferred way to perform boolean tests in Python is if foo and if not foo.

However, from a technical point of view, there's nothing wrong with using is True and is False. In PEP 285 (which defined the bool type):

The values False and True will be singletons, like None. Because the type has two values, perhaps these should be called "doubletons"? The real implementation will not allow other instances of bool to be created.

So whenever you use True or False you end up with the same instance.

ThiefMaster
  • 310,957
  • 84
  • 592
  • 636
  • Is this just a shorthand introduced into the language for `is` or `==`? – Lord Cat Apr 03 '15 at 16:46
  • I didn't know that the language specifically defined `True` and `False` as singletons. +1 just for that. – Mark Ransom Apr 03 '15 at 16:50
  • 3
    Actually it's a different thing. `x is True` tests if `x` is actually the same thing as `True`, so only an actual `True` will satisfy this test. `x == True` would also accept `x` being an instance of a class containing e.g. `__eq__(self, other): return True`. And if you just test for `x` or `not x` all you check is if the value is "truthy" or "falsy" - and empty collections are falsy for example. – ThiefMaster Apr 03 '15 at 16:50
  • I see. Hence why `1 == True` is `True`, but `1 is True` is `False` (as 1 is "truthy" but is not the same as the singleton `True` (is not stored in the same memory location)). But I am correct in thinking that `if x:` is exactly the same thing as `if x == True:`, am I not? – Lord Cat Apr 03 '15 at 20:44
  • You are not. `if x` tests for truthiness. For example, `x = [0]` would be truthy but not `== True`. The reason why `1 == True` is true is that `bool` is a subclass of `int` and `True` has the value `1` (`False` has the value `0`) – ThiefMaster Apr 03 '15 at 22:48
2

One reason that you don't do x is <True/False> or x == <True/False> is that you aren't always testing for True or False. Take the following code:

user_input = raw_input(' > ')
if user_input:
    ...

This will not work correctly if you do user_input is True or user_input == True, neither of which will ever evaluate truth-y. There are plenty of other examples where truth-y and false-y objects should be as acceptable as True and False themselves, and e.g.

if bool(user_input) is True:

is rather less readable.

jonrsharpe
  • 115,751
  • 26
  • 228
  • 437