defaultdict等效于列表

时间:2012-01-03 22:29:36

标签: python collections containers defaultdict

有没有\你如何建立一个非常有用的collections.defaultdict等效的python?

想象一下这种容器的用法:

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

更新:我添加了follow up question以向此构造添加更多功能

5 个答案:

答案 0 :(得分:10)

我认为使用它会有点混乱;然而,这是我第一次想到如何做到这一点:

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)

这需要一个可调用的(我认为这是默认值的工作原理)默认值。

当我跑步时:

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

我回来了:

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

答案 1 :(得分:3)

如果你需要的只是索引访问而不是切片/附加等,那么只需使用defaultdict

(如果你真的想要perl / js语义,你可以继承列表__get____set__

答案 2 :(得分: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']

答案 3 :(得分:1)

来自@Finn回答的略微增强的版本。

class defaultlist(list):
    """List returning default value when accessing uninitialized index.

    Original implementation: http://stackoverflow.com/a/8719940/315168
    """

    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)

    def __getitem__(self, index):
        """Allows self.dlist[0] style access before value is initialized."""
        while len(self) <= index:
            self.append(self._fx())
        return list.__getitem__(self, index)

答案 4 :(得分:0)

也许最简单的方法是使用词典:

>>> a = {}
>>> a[2] = 7
>>> a[4] = 'x'
>>> [a[i] if i in a else 0 for i in xrange(max(a) + 1)]
[0, 0, 7, 0, 'x']