列表的defaultdict等价物

13 投票
5 回答
3073 浏览
提问于 2025-04-17 09:29

有没有办法构建一个和Python中非常有用的collections.defaultdict相似的东西呢?

想象一下使用这种容器的场景:

>>> a = collections.defaultlist(0)
>>> a[2]=7
>>> a[4]='x'
>>> a
[0,0,7,0,'x']

更新:我添加了一个后续问题,想要为这个构造增加更多功能

5 个回答

2

我的建议:

def xtend(f):
    def wrap(self, index, *args):
        if len(self) <= index:
            self.extend([self._gen()] * (index - len(self) + 1))
        return f(self, index, *args)
    return wrap

class defaultlist(list):
    def __init__(self, gen, lst = []):
        list.__init__(self, lst)
        self._gen = gen

    __setitem__ = xtend(list.__setitem__)
    __getitem__ = xtend(list.__getitem__)

结果:

>>> a = defaultlist(int, [1, 2, 3])
>>> a[10] = 'x'
>>> a[2] = 7
>>> print a
[1, 2, 7, 0, 0, 0, 0, 0, 0, 0, 'x']
4

如果你只需要的是索引访问,而不是切片、添加等功能,那么就直接使用defaultdict吧。

(如果你真的想要像perl或js那样的行为,可以通过继承列表来实现__get____set__方法。)

12

我觉得这样用起来可能会有点让人困惑,不过这是我对怎么做的初步想法:

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)

这需要一个可以调用的东西(我想这就是defaultdict的工作原理),用来设置默认值。

当我运行:

a = defaultlist(int)
print a
a[2] = 7
a[4] = 'x'
print a

我得到的结果是:

[]
[0, 0, 7, 0, 'x']

撰写回答