列表和字典的__getitem__对比

0 投票
1 回答
3275 浏览
提问于 2025-04-18 04:15

字典__getitem__ 方法似乎和 列表 的工作方式不太一样,这让我感到困惑。我的意思是:

如果我创建一个 list 的子类,我可以像这样重写 __getitem__ 方法:

class myList(list):
    def __getitem__(self,index):
        if isinstance(index,int):
            #do one thing
        if isinstance(index,slice):
            #do another thing

但是,如果我创建一个 dict 的子类,__getitem__ 方法就不会使用 索引,而是使用 ,就像这样:

class myDict(dict):
    def __getitem__(self,key):
        #Here I want to inspect the INDEX, but only have access to key!

所以,我的问题是,如何才能获取字典的 索引,而不仅仅是

举个例子:

a = myDict()
a['scalar'] = 1  # Create dictionary entry called 'scalar', and assign 1
a['vector_1'] = [1,2,3,4,5]  # I want all subsequent vectors to be 5 long
a['vector_2'][[0,1,2]] = [1,2,3]  # I want to intercept this and force vector_2 to be 5 long
print(a['vector_2'])
[1,2,3,0,0]
a['test']  # This should throw a KeyError
a['test'][[0,2,3]]  # So should this

1 个回答

3

字典是没有顺序的;它没有像列表那样的索引可以使用。这就是为什么在Python中,字典和列表都可以用相同的语法([..])和相同的魔法方法(__getitem__)来处理。

当你用一个整数,比如 0,去索引一个字典时,字典会把这个整数当作其他任何键来处理:

>>> d = {'foo': 'bar', 0: 42}
>>> d.keys()
[0, 'foo']
>>> d[0]
42
>>> d['foo']
'bar'

链式索引适用于返回值;这个表达式:

a['vector_2'][0, 1, 2]

会被执行为:

_result = a['vector_2']  # via a.__getitem__('vector_2')
_result[0, 1, 2]         # via _result.__getitem__((0, 1, 2))

所以如果你想让字典里的以某种方式表现,你必须返回支持那些操作的对象。

撰写回答