defaultdict的defaultdict,嵌套

有没有办法使defaultdict也是defaultdict的默认值? IOW,如果我这样做:

x = defaultdict(...stuff...) x[0][1][0] {} 

这就是我想要的。 我可能只是最终使用一堆模式,但是当我意识到我不知道如何做到这一点,这让我感兴趣。

所以,我可以这样做:

 x = defaultdict(defaultdict) 

但这只是一个层面:

 x[0] {} x[0][0] KeyError: 0 

有食谱可以做到这一点。 但是可以简单地使用正常的defaultdict参数来完成吗?

请注意,有人将其标记为Python的重复项:defaultdict的defaultdict? ,但这不是同一个问题…那个问题是如何做一个两级的defaultdict; 这一个是如何做一个无限级的recursiondefaultdict。

对于任意数量的级别:

 def rec_dd(): return defaultdict(rec_dd) >>> x = rec_dd() >>> x['a']['b']['c']['d'] defaultdict(<function rec_dd at 0x7f0dcef81500>, {}) >>> print json.dumps(x) {"a": {"b": {"c": {"d": {}}}}} 

当然你也可以用lambda来做这个,但是我觉得lambdas的可读性不好。 无论如何,它会是这样的:

 rec_dd = lambda: defaultdict(rec_dd) 

这里的其他答案告诉你如何创build一个包含“无限多” defaultdict ,但是它们不能解决我认为可能是你最初需要的东西,那就是只有一个双深度defaultdict。

您可能一直在寻找:

 defaultdict(lambda: defaultdict(dict)) 

你可能更喜欢这种结构的原因是:

  • 它比recursion解决scheme更加明确,因此读者可能更容易理解。
  • 这使得defaultdict的“叶子”可以是除字典之外的东西,例如: defaultdict(lambda: defaultdict(list))defaultdict(lambda: defaultdict(set))

有这样一个漂亮的伎俩:

 tree = lambda: defaultdict(tree) 

然后你可以用x = tree()来创build你的x

与BrenBarn的解决scheme类似,但是不包含variablestree的名称两次,所以即使在variables字典发生变化之后,它也可以工作:

 tree = (lambda f: f(f))(lambda a: (lambda: defaultdict(a(a)))) 

然后你可以用x = tree()来创build每个新的x


对于def版本,如果tree名被反弹,我们可以使用函数闭包范围来保护数据结构免受现有实例停止工作的缺陷的影响。 它看起来像这样:

 from collections import defaultdict def tree(): def the_tree(): return defaultdict(the_tree) return the_tree()