使用布尔索引从Python列表中访问元素

4
我最近发现了一种在 Python 中索引列表的方法。我以前从未见过这种方法,所以我想要清楚地理解它。
我有一个列表 `["Peter", "James", "Mark"]`,如果我使用布尔值 `False` 索引它,它会返回 `Peter`,如果我使用 `True` 进行索引,它会返回 `James`,如下所示:
- `["Peter", "James", "Mark"][False] => Peter` - `["Peter", "James", "Mark"][True] => James`
我想知道这里发生了什么,以及这种方法叫什么?

2
@xg.plt.py,我错了。请看下面wim的答案。 - Keyur Potdar
2个回答

6
这里的数据模型钩子是 __index__ 魔法方法:
>>> True.__index__()
1
>>> False.__index__()
0

__index__方法返回的值用于访问对象的subscription,允许使用任意对象进行索引和切片操作:

x[obj]

这与 boolint 的子类无关!您可以使用任何对象实现相同的效果。

>>> class A:
...     def __index__(self):
...         return 1
...     
>>> 'ab'[A()]
'b'

对于 int 的子类,是否解析 __index__ 取决于实现细节。

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根据Python数据模型正确地运行。看起来CPython正在采取一种快捷/性能优化方式。


一个 MyInt 已经是 int 类型,所以 Python 实际上不需要执行 int 类型转换。我认为两个结果都符合数据模型。 - user2357112

2
在Python中,bool类派生自int。因此,True=1False=0print (True + True)将输出2
因此,在列表['peter','john','abhi'] [True]上,返回列表的第二个元素,即john

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接