在python中创建defaultlist

2024-05-17 12:43:18 发布

您现在位置:Python中文网/ 问答频道 /正文

我正在尝试为非常有用的^{}创建一个等价的列表。下面的设计工作得很好:

class defaultlist(list):
    def __init__(self, fx):
        self._fx = fx
    def __setitem__(self, index, value):
        while len(self) <= index:
            self.append(self._fx())
        list.__setitem__(self, index, value)

以下是使用方法:

>>> dl = defaultlist(lambda:'A')
>>> dl[2]='B'
>>> dl[4]='C'
>>> dl
['A', 'A', 'B', 'A', 'C']

为了支持以下行为,我应该向defaultlist添加什么?

>>> dl = defaultlist(dict)
>>> dl[2]['a'] = 1
>>> dl
[{}, {}, {'a':1}]

Tags: self列表indexleninitvaluedeflist
2条回答

在您给出的示例中,首先尝试检索列表中不存在的值,正如您所做的那样,dl[2]['a'],Python首先检索列表中的第三个(索引2)元素,然后继续在该对象上获取名为“a”的元素,因此您还必须实现对__getitem__方法的自动扩展行为,如下所示:

class defaultlist(list):
    def __init__(self, fx):
        self._fx = fx
    def _fill(self, index):
        while len(self) <= index:
            self.append(self._fx())
    def __setitem__(self, index, value):
        self._fill(index)
        list.__setitem__(self, index, value)
    def __getitem__(self, index):
        self._fill(index)
        return list.__getitem__(self, index)

有一个可用的python包:

$ pip install defaultlist

默认情况下,添加的索引将填充为“无”。

>>> from defaultlist import defaultlist
>>> l = defaultlist()
>>> l
[]
>>> l[2] = "C"
>>> l
[None, None, 'C']
>>> l[4]
>>> l
[None, None, 'C', None, None]

切片和负片也同样支持

>>> l[1:4]
[None, 'C', None]
>>> l[-3]
'C'

可以通过lambda创建简单的工厂函数。

>>> l = defaultlist(lambda: 'empty')
>>> l[2] = "C"
>>> l[4]
'empty'
>>> l
['empty', 'empty', 'C', 'empty', 'empty']

还可以实现先进的工厂功能:

>>> def inc():
...     inc.counter += 1
...     return inc.counter
>>> inc.counter = -1
>>> l = defaultlist(inc)
>>> l[2] = "C"
>>> l
[0, 1, 'C']
>>> l[4]
4
>>> l
[0, 1, 'C', 3, 4]

有关详细信息,请参阅Documentation

相关问题 更多 >