Accessing elements from a Python list using Boolean indexing
Question:
I recently came across this way of indexing a list in Python. I’ve never seen this one before, so I would like to understand this clearly.
I have a list ["Peter", "James", "Mark"]
and if I index it using the boolean value False
it returns Peter
and if I index it using True
it returns James
, as given below
["Peter", "James", "Mark"][False] => Peter
["Peter", "James", "Mark"][True] => James
I would like to know what happens here and what is this method called as?
Answers:
The datamodel hook here is the __index__
magic method:
>>> True.__index__()
1
>>> False.__index__()
0
The value returned by on obj’s __index__
is used when accessing with subscription, allowing arbitrary objects to be used for indexing and slicing:
x[obj]
This is somewhat independent of the fact that bool
is a subclass of int
! You may achieve the same with any object.
>>> class A:
... def __index__(self):
... return 1
...
>>> 'ab'[A()]
'b'
Whether __index__
is resolved for int
subclasses depends on implementation detail.
CPython 3.7.1:
>>> class MyInt(int):
... def __index__(self):
... return 1
...
>>> '01'[MyInt(0)]
'0'
PyPy 5.0.1:
>>>> class MyInt(int):
.... def __index__(self):
.... return 1
....
>>>> '01'[MyInt(0)]
'1'
PyPy behaves correctly according to the Python datamodel. Looks like CPython is taking a shortcut / performance optimization.
In Python, bool
class is derived from of int
Hence True=1
and False=0
print (True + True)
will give an output 2
So on a list ['peter', 'john', 'abhi'][True]
returns 2nd element of the list i.e. john
I recently came across this way of indexing a list in Python. I’ve never seen this one before, so I would like to understand this clearly.
I have a list ["Peter", "James", "Mark"]
and if I index it using the boolean value False
it returns Peter
and if I index it using True
it returns James
, as given below
["Peter", "James", "Mark"][False] => Peter
["Peter", "James", "Mark"][True] => James
I would like to know what happens here and what is this method called as?
The datamodel hook here is the __index__
magic method:
>>> True.__index__()
1
>>> False.__index__()
0
The value returned by on obj’s __index__
is used when accessing with subscription, allowing arbitrary objects to be used for indexing and slicing:
x[obj]
This is somewhat independent of the fact that bool
is a subclass of int
! You may achieve the same with any object.
>>> class A:
... def __index__(self):
... return 1
...
>>> 'ab'[A()]
'b'
Whether __index__
is resolved for int
subclasses depends on implementation detail.
CPython 3.7.1:
>>> class MyInt(int):
... def __index__(self):
... return 1
...
>>> '01'[MyInt(0)]
'0'
PyPy 5.0.1:
>>>> class MyInt(int):
.... def __index__(self):
.... return 1
....
>>>> '01'[MyInt(0)]
'1'
PyPy behaves correctly according to the Python datamodel. Looks like CPython is taking a shortcut / performance optimization.
In Python, bool
class is derived from of int
Hence True=1
and False=0
print (True + True)
will give an output 2
So on a list ['peter', 'john', 'abhi'][True]
returns 2nd element of the list i.e. john