列表的defaultdict等价物
有没有办法构建一个和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']