14

Indexing on list with boolean values works fine. Though the index should be an integer.

Following is what I tried in console:

>>> l = [1,2,3,4,5,6]
>>> 
>>> l[False]
1
>>> l[True]
2
>>> l[False + True]
2
>>> l[False + 2*True]
3
>>> 
>>> l['0']
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
TypeError: list indices must be integers, not str
>>> type(True)
<type 'bool'>

When I tried l['0'] it printed error that int type expected in indices and that is obvious. Then, even the type of 'True' and 'False' being Bool, indexing on the list works fine and automatically converts it to int type and performs the operation.

Please explain what is going on internally. I am posting question for the first time, so please forgive me for any mistake.

Pierre GM
  • 19,809
  • 3
  • 56
  • 67
Somesh
  • 1,235
  • 2
  • 13
  • 29

4 Answers4

21

What's going on is that booleans actually are integers. True is 1 and False is 0. Bool is a subtype of int.

>>> isinstance(True, int)
True
>>> issubclass(bool, int)
True

So it's not converting them to integers, it's just using them as integers.

(Bools are ints for historical reasons. Before a bool type existed in Python, people used the integer 0 to mean false and 1 to mean true. So when they added a bool type, they made the boolean values integers in order to maintain backward compatibility with old code that used these integer values. See for instance http://www.peterbe.com/plog/bool-is-int .)

>>> help(True)
Help on bool object:

class bool(int)
 |  bool(x) -> bool
 |  
 |  Returns True when the argument x is true, False otherwise.
 |  The builtins True and False are the only two instances of the class bool.
 |  The class bool is a subclass of the class int, and cannot be subclassed.
Ashwini Chaudhary
  • 244,495
  • 58
  • 464
  • 504
BrenBarn
  • 242,874
  • 37
  • 412
  • 384
  • 2
    +1, I learned something. Did not know `bool` was a subclass of `int`. – nneonneo Oct 04 '12 at 06:47
  • I had just gone through this post too [link]http://stackoverflow.com/questions/3174392/is-it-pythonic-to-use-bools-as-ints/3175293#3175293) Thanks a lot. – Somesh Oct 04 '12 at 08:33
3

Python used to lack booleans, we just used integers, 0 for False and any other integer for True. So when booleans were added to the language, the values False and True, can be treated as the integer values 0 and 1 still by the interpreter, to help backwards compatibility. Internally, bool is a sub-class of int.

In other words, the following equations are True:

>>> False == 0
True
>>> True == 1
True
>>> isinstance(True, int)
True
>>> issubclass(bool, int)
True

and as you found out:

>>> True * 3
3

This doesn't extend to strings however.

Aran-Fey
  • 39,665
  • 11
  • 104
  • 149
Martijn Pieters
  • 1,048,767
  • 296
  • 4,058
  • 3,343
2

...Booleans are a subtype of plain integers.

Source.

As you can see, False is 0 and True is 1.

Bernhard Wagner
  • 1,681
  • 12
  • 15
alex
  • 479,566
  • 201
  • 878
  • 984
-1

The Python source documentation does not mention directly that all non-zero integers are evaluate to True when passed to an if statement, while only zero evaluates to False. You can prove it to yourself with the following code in Python:

for test_integer in range(-2, 3, ):
    if not test_integer:
        print('{} evaluates to False in Python.'.format(test_integer))
    else:
        print('{} evaluates to True in Python.'.format(test_integer))
>>>-2 evaluates to True in Python.
-1 evaluates to True in Python.
0 evaluates to False in Python.
1 evaluates to True in Python.
2 evaluates to True in Python.

Try it for as far on either side of zero as you want; this code only shows for -2, -1, 0, 1, and 2 inclusive.

brethvoice
  • 350
  • 1
  • 4
  • 14
  • 2
    The question is the other way around. The list index being converted from Boolean to Int but not from String to Int. – line-o Feb 07 '20 at 22:22
  • @line-o the question just asked about "what is going on internally," and I attempted to answer that in a way that made sense to me. I do appreciate the downvote and feedback though. – brethvoice Feb 20 '20 at 20:38