使用布尔索引从Python列表中切割元素

thi*_*pan 4 python list slice python-3.x

我最近遇到过用Python切片列表的方式.我以前从未见过这个,所以我想清楚地理解这一点.

我有一个列表["Peter", "James", "Mark"],如果我使用False它返回的布尔值Peter切片,如果我使用True它切片返回James,如下所示

  • ["Peter", "James", "Mark"][False] => Peter
  • ["Peter", "James", "Mark"][True] => James

我想知道这里发生了什么,这个方法叫做什么?

wim*_*wim 6

这里的datamodel钩子是__index__神奇的方法:

>>> True.__index__()
1
>>> False.__index__()
0
Run Code Online (Sandbox Code Playgroud)

__index__当使用下标访问时,使用on obj返回的值,允许任意对象与切片一起使用:

x[obj]
Run Code Online (Sandbox Code Playgroud)

这有点独立于bool作为子类的事实int!您可以使用任何对象实现相同的目标.

>>> class A:
...     def __index__(self):
...         return 1
...     
>>> 'ab'[A()]
'b'
Run Code Online (Sandbox Code Playgroud)

是否__index__int子类解析取决于实现细节.

CPython 3.7.1:

>>> class MyInt(int):
...     def __index__(self):
...         return 1
... 
>>> '01'[MyInt(0)]
'0'
Run Code Online (Sandbox Code Playgroud)

PyPy 5.0.1:

>>>> class MyInt(int):
....     def __index__(self):
....         return 1
....         
>>>> '01'[MyInt(0)]
'1'
Run Code Online (Sandbox Code Playgroud)

PyPy根据Python数据模型正确运行.看起来CPython正在进行快捷/性能优化.