这是创建递归defaultdict 的一种非常聪明的方法。一开始理解起来有点棘手,但一旦深入了解发生了什么,它实际上是递归的一个非常简单的用法。
在本例中,我们定义了一个递归 lambda 函数 tree,它返回一个 defaultdict,其构造函数为 tree。为了清楚起见,让我们使用常规函数重写它。
from collections import defaultdict
from pprint import pprint
def get_recursive_dict():
return defaultdict(get_recursive_dict)
请注意,我们返回的是 defaultdict(get_recursive_dict) 而不是 defaultdict(get_recursive_dict())。我们想要传递defaultdict 一个可调用对象(即函数get_recursive_dict)。实际上调用get_recursive_dict() 会导致无限递归。
如果我们调用get_recursive_dict,我们会得到一个空的defaultdict,它的默认值是函数get_recursive_dict。
recursive_dict = get_recursive_dict()
print(recursive_dict)
# defaultdict(<function get_recursive_dict at 0x0000000004FFC4A8>, {})
让我们看看它的实际效果。创建键'alice',其对应的值默认为空defaultdict,其默认值为函数get_recursive_dict。请注意,这与我们的recursive_dict 相同的默认值!
print(recursive_dict['alice'])
# defaultdict(<function get_recursive_dict at 0x0000000004AF46D8>, {})
print(recursive_dict)
# defaultdict(<function get_recursive_dict at 0x0000000004AF46D8>, {'alice': defaultdict(<function get_recursive_dict at 0x0000000004AF46D8>, {})})
所以我们可以创建任意数量的嵌套字典。
recursive_dict['bob']['age'] = 2
recursive_dict['charlie']['food']['dessert'] = 'cake'
print(recursive_dict)
# defaultdict(<function get_recursive_dict at 0x00000000049BD4A8>, {'charlie': defaultdict(<function get_recursive_dict at 0x00000000049BD4A8>, {'food': defaultdict(<function get_recursive_dict at 0x00000000049BD4A8>, {'dessert': 'cake'})}), 'bob': defaultdict(<function get_recursive_dict at 0x00000000049BD4A8>, {'age': 2}), 'alice': defaultdict(<function get_recursive_dict at 0x00000000049BD4A8>, {})})
一旦你用一个键覆盖了默认值,你就不能再创建任意深度的嵌套字典了。
recursive_dict['bob']['age']['year'] = 2016
# TypeError: 'int' object does not support item assignment
我希望这能解决问题!