34

Possible Duplicate:
Is False == 0 and True == 1 in Python an implementation detail or is it guaranteed by the language?

A brief transcript from my interactive console:

Python 2.7.2 (default, Jun 29 2011, 11:10:00) 
[GCC 4.6.1] on linux2
Type "help", "copyright", "credits" or "license" for more information.
>>> True
True
>>> 0 == True
False
>>> 1 == True
True
>>> 2 == True
False

Why on earth is this the case?

Edit: For the sake of contrast, consider the is operator.

>>> 0 is False
False
>>> 1 is True
False
>>> 0 is 0
True
>>> True is True
True

That makes a lot of sense because though 1 and True both mean the same thing as the condition of an if statement, they really aren't the same thing.

Edit again: More fun consequences of 1 == True:

>>> d = {}
>>> d[True] = "hello"
>>> d[1]
"hello"
Community
  • 1
  • 1
Clueless
  • 3,984
  • 1
  • 20
  • 27

8 Answers8

37

Because Boolean in Python is a subtype of integers. From the documentation:

Boolean values are the two constant objects False and True. They are used to represent truth values (although other values can also be considered false or true). In numeric contexts (for example when used as the argument to an arithmetic operator), they behave like the integers 0 and 1, respectively. The built-in function bool() can be used to cast any value to a Boolean, if the value can be interpreted as a truth value (see section Truth Value Testing above).

http://docs.python.org/library/stdtypes.html#boolean-values

Datajam
  • 4,141
  • 2
  • 23
  • 25
  • 1
    Yeah, this explains *how*, but it seems like a strange decision. It means `==` has very strange behavior. I like the behavior of the `is` operator way better, where booleans and integers are never equal to each other. – Clueless Aug 20 '11 at 22:18
  • 9
    @Clueless: Be careful with `is`, becuase *integers* are sometimes not equal to each other, either: [Python "is" operator behaves unexpectedly with integers](http://stackoverflow.com/questions/306313/python-is-operator-behaves-unexpectedly-with-integers) – Greg Hewgill Aug 20 '11 at 22:22
  • +1 for quoting the documentation. The section on Truth Value Testing is also very important to read. – machine yearning Aug 20 '11 at 22:23
  • @Greg Well, that's depressing. So I have to use `==` and I can't rely on it separating types cleanly... – Clueless Aug 20 '11 at 22:29
  • 2
    @Clueless The designer of Python _chose_ to allow values of one type to behave as values of another type seemingly more frequently than not. Python is not like Java where booleans and integers are not implicitly interchangeable. That said, when "separation" is desired, you can use [Python's built-in `type` function](http://docs.python.org/library/functions.html#type). – Ray Toal Aug 20 '11 at 22:53
  • @Ray Toal There was actually quite some discussion about exactly this topic when bools were implemented. I think the final reason they went with the current implementation was backwards compatibility (though I fear the day when I find a program that uses integer arithmetic on booleans) – Voo Aug 21 '11 at 01:49
  • @Voo It's occasionally helpful when doing code golf. `("thing 1","thing 2")[x==0]`. I'm not sure "helpful for code golf" is a good thing for any language feature though. – Clueless Aug 21 '11 at 04:58
28

Because instances of bool are also instances of int in python. True happens to be equals to integer 1.

Take a look at this example:

[GCC 4.2.1 (Based on Apple Inc. build 5658) (LLVM build 2335.15.00)] on darwin
Type "help", "copyright", "credits" or "license" for more information.
>>> isinstance(True, int)
True
>>> int(True)
1
>>> 
Pablo Santa Cruz
  • 176,835
  • 32
  • 241
  • 292
  • 1
    Sorry to rain on a good answer but `` There is no type `boolean` -- it's `bool`, and `isinstance(bool, int) == False`, so I think you meant to say "Instances of `bool` are also instances of `int`" or "Boolean values are instances of `int`". `` Cheers. – Ray Toal Aug 20 '11 at 22:19
  • @Ray Toal: Thanks for pointing that out. Very helpful. Corrected the answer to reflect what you have just mentioned. – Pablo Santa Cruz Aug 20 '11 at 22:33
  • 1
    Great, now here's an upvote for a Nice Answer badge. Good use of `isinstance` by the way. Gets to the point of why `2 != True` nicely. – Ray Toal Aug 20 '11 at 22:46
13

It's standard binary conventions: 1 is true, 0 is false.

It's like 1 means "on" in machine language, and 0 means "off".

Because of this the bool type is just a subtype of int in Python, with 1 == True and 0 == False.

However any non-zero numeric value will be evaluated as True in a conditional statement:

>>> if 2: print "ok"
ok
>>> 2 == True
False
machine yearning
  • 9,889
  • 5
  • 38
  • 51
  • Actually there's at least one language where true is defined as -1 (and actually Win32 uses that definition rarely as well). Has lead to some quite interesting bugs I hear. – Voo Aug 21 '11 at 01:59
  • To explain my answer, the original question did not mention that `2 != True`, it was just "Why does `1 == True` in python?" It was edited later – machine yearning Apr 22 '16 at 09:40
12

Once upon a time (in Python < 2.3), there was no boolean type, no False or True, only 0 and 1. Then PEP 285 came along and thus they were added to the language. They were defined so that True == 1 and False == 0, probably for reasons of backwards compatibility.

hammar
  • 138,522
  • 17
  • 304
  • 385
5

Equality testing is different than boolean testing:

>>> bool(1)
True
>>> bool(2)
True
>>> bool(-1)
True
>>> bool(0)
False
Ross Patterson
  • 5,702
  • 20
  • 38
  • It just seems to me like `==` should either recognize all values that are "true" as interpreted by python or it should be strict. It's not loosey-goosey because `2 == True` evaluates to false, and it's not strict because `1 == True` evaluates to true even though they are totally different types. So it's inconsistent. – Clueless Aug 20 '11 at 22:15
  • 3
    @Clueless But if you allowed that, you could "prove" `1==2` since you'd expect the equality operation to be transitive (and therefore `1 == True == 2`). Now that's quite inconsistent as well and much more problematic imo ;) – Voo Aug 21 '11 at 02:18
  • 1
    It's not actually *that* far out. It's just an equivalence class on non-zero integers. But I agree, we don't want `1 == 2` to be true in general because it would make for a pretty useless operator. Much better would be just make `1 == True` be false, seeing as they are totally different things mathematically. – Clueless Aug 21 '11 at 04:55
0

It's a boolean thing. 1 == true, 0 == false.

goddamnyouryan
  • 6,854
  • 15
  • 56
  • 105
0

because in binary 1 is true and 0 is false. it also happens in PHP.

I'm not sure about other languages, but I think it's going to be the same.

bbnn
  • 3,505
  • 10
  • 50
  • 68
-1

It's binary. 0 is always False and 1 is always True. In python though any non-zero value, including negative values are always True.

>>> if -1:
...     print 'a'
...
a
>>> if 2:
...     print 'a'
...
a
>>> if 0:
...     print 'a'
...
>>>
Ben
  • 51,770
  • 36
  • 127
  • 149
  • 3
    -1 `In python though any non-zero value, including negative values are always True.` -- he just pasted a snippet that demonstrates that this is not the case. – Gabi Purcaru Aug 20 '11 at 22:08
  • As Bill Clinton might say, it depends what the meaning of "are" is. `2 is True` is false (as is `1 is True`). Sure, `bool()` will return `True` for non-zero integer inputs, but that doesn't mean the values "are" `True`. – Wooble Aug 20 '11 at 22:12
  • The snippet proves that 2 is not a binary number. It doesn't prove that python evaluates non-zero numbers, lists etc as true. – Ben Aug 20 '11 at 22:15
  • 1
    This answer kind of sidesteps the question. The OP wanted to know why `1 == True` but `2 != True`. Equality is different from "evaluation in a boolean context." – Ray Toal Aug 20 '11 at 22:58