是否有标准类用于无限嵌套的defaultdict?
有没有人知道在Python中有没有一个标准的类,可以创建一个可以无限嵌套的字典?
我发现自己总是在重复这个模式:
d = defaultdict(lambda: defaultdict(lambda: defaultdict(int)))
d['abc']['def']['xyz'] += 1
如果我想再加一层(比如 d['abc']['def']['xyz']['wrt']
),我就得再定义一个嵌套的defaultdict。
为了让这个模式更通用,我写了一个简单的类,重写了 __getitem__
方法,这样可以自动创建下一个嵌套的字典。
例如:
d = InfiniteDict(('count',0),('total',0))
d['abc']['def']['xyz'].count += 0.24
d['abc']['def']['xyz'].total += 1
d['abc']['def']['xyz']['wrt'].count += 0.143
d['abc']['def']['xyz']['wrt'].total += 1
不过,有没有人知道有没有现成的实现可以用这个想法?我试着在网上搜索,但不太确定这个东西该叫什么。
6 个回答
15
这很自然地适合用递归的方式来定义。
>>> import collections
>>> def nested_dd():
... return collections.defaultdict(nested_dd)
...
>>> foo = nested_dd()
>>> foo
defaultdict(<function nested_dd at 0x023F0E30>, {})
>>> foo[1][2]=3
>>> foo[1]
defaultdict(<function nested_dd at 0x023F0E30>, {2: 3})
>>> foo[1][2]
3
29
我觉得这个一行代码几乎是完美的解决方案:
>>> from collections import defaultdict
>>> infinite_defaultdict = lambda: defaultdict(infinite_defaultdict)
>>> d = infinite_defaultdict()
>>> d['x']['y']['z'] = 10
这是Raymond Hettinger在推特上分享的内容 (https://twitter.com/raymondh/status/343823801278140417)
14
你可以从 defaultdict
这个类派生出你想要的功能:
class InfiniteDict(defaultdict):
def __init__(self):
defaultdict.__init__(self, self.__class__)
class Counters(InfiniteDict):
def __init__(self):
InfiniteDict.__init__(self)
self.count = 0
self.total = 0
def show(self):
print "%i out of %i" % (self.count, self.total)
使用这个类的方式大概是这样的:
>>> d = Counters()
>>> d[1][2][3].total = 5
>>> d[1][2][3].show()
0 out of 5
>>> d[5].show()
0 out of 0