I recently came across this way of slicing 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 slice it using the boolean value False it returns Peter and if I slice 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 subscripting, allowing arbitrary objects to be used with slices:
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.