Cor*_*man 109 python recursion defaultdict
有没有办法使defaultdict也成为defaultdict的默认值?(即无限级递归defaultdict?)
我希望能够做到:
x = defaultdict(...stuff...)
x[0][1][0]
{}
Run Code Online (Sandbox Code Playgroud)
所以,我可以这样做x = defaultdict(defaultdict),但那只是第二级:
x[0]
{}
x[0][0]
KeyError: 0
Run Code Online (Sandbox Code Playgroud)
有些食谱可以做到这一点.但是它可以简单地使用普通的defaultdict参数吗?
注意这是在询问如何进行无限级别的递归defaultdict,所以它与Python不同:defaultdict的defaultdict?,这是如何做一个两级默认.
我可能最终会使用束模式,但当我意识到我不知道如何做到这一点时,它让我感兴趣.
And*_*ark 143
对于任意数量的级别:
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": {}}}}}
Run Code Online (Sandbox Code Playgroud)
当然你也可以用lambda来做这件事,但我觉得lambda不太可读.在任何情况下,它看起来像这样:
rec_dd = lambda: defaultdict(rec_dd)
Run Code Online (Sandbox Code Playgroud)
Chr*_* W. 138
这里的其他答案告诉你如何创建一个defaultdict包含"无限多"的内容defaultdict,但是它们无法解决我认为最初需要的问题,即只需要两个深度的默认值.
您可能一直在寻找:
defaultdict(lambda: defaultdict(dict))
Run Code Online (Sandbox Code Playgroud)
您可能更喜欢这种结构的原因是:
defaultdict成为字典以外的东西,例如:defaultdict(lambda: defaultdict(list))或defaultdict(lambda: defaultdict(set))Bre*_*arn 41
这样做有一个很好的技巧:
tree = lambda: defaultdict(tree)
Run Code Online (Sandbox Code Playgroud)
然后你可以创建你x的x = tree().
pts*_*pts 20
与BrenBarn的解决方案类似,但不包含变量的名称tree两次,因此即使在更改变量字典后也能正常工作:
tree = (lambda f: f(f))(lambda a: (lambda: defaultdict(a(a))))
Run Code Online (Sandbox Code Playgroud)
然后你可以创建每个新x的x = tree().
对于def版本,我们可以使用函数闭包范围来保护数据结构免受现有实例在tree名称反弹时停止工作的缺陷的影响.它看起来像这样:
from collections import defaultdict
def tree():
def the_tree():
return defaultdict(the_tree)
return the_tree()
Run Code Online (Sandbox Code Playgroud)
小智 6
我还将提出更多OOP样式的实现,该实现支持无限嵌套以及正确格式化repr。
class NestedDefaultDict(defaultdict):
def __init__(self, *args, **kwargs):
super(NestedDefaultDict, self).__init__(NestedDefaultDict, *args, **kwargs)
def __repr__(self):
return repr(dict(self))
Run Code Online (Sandbox Code Playgroud)
用法:
my_dict = NestedDefaultDict()
my_dict['a']['b'] = 1
my_dict['a']['c']['d'] = 2
my_dict['b']
print(my_dict) # {'a': {'b': 1, 'c': {'d': 2}}, 'b': {}}
Run Code Online (Sandbox Code Playgroud)