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.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With