【问题标题】:Understanding nested defaultdict and `tree = lambda: defaultdict(tree)` vs `tree = defaultdict(lambda: tree)`理解嵌套的 defaultdict 和 `tree = lambda: defaultdict(tree)` vs `tree = defaultdict(lambda: tree)`
【发布时间】:2021-11-28 18:51:35
【问题描述】:

工作形式

another question,我看到了如何创建一个defaultdict of defaultdict of defaultdict...为:

Working form Using it Output
tree = lambda: defaultdict(tree)
x = tree()
x["1"]
x["2"]
x["1"]["3"]

print(json.dumps(x))
{"1": {"2": {}}, "2": {}}

它可以正常工作,但我无法理解它。


非工作形式

另外,为什么以下内容根本不起作用:

Non Working form Using it Output
tree = defaultdict(lambda: tree)
x = tree
x["1"]
x["2"]
x["1"]["3"]

print(json.dumps(x))
ValueError: Circular reference detected

谁能解释一下tree = lambda: defaultdict(tree) 是如何工作的以及为什么tree = defaultdict(lambda: tree) 不工作?


编辑:@Samwise 在 cmets 中指出 treedefaultdict 的每个参数都必须是可调用的,因此要使第二种形式起作用,它必须是:

tree = lambda: defaultdict(lambda: tree())

但是由于lambda: tree()等价于tree,所以这个修改后的形式和第一种形式是等价的。

【问题讨论】:

  • 您希望它是 defaultdict(lambda: tree()) 以产生与 defaultdict(tree) 相同的结果。否则,tree 函数本身永远不会被调用。
  • 在第二个中,tree 是一个特定的 defaultdict,它使用的默认值是相同的 defaultdict。在第一个中,每次执行tree 都会创建一个新的defaultdict。
  • @Samwise,谢谢。我试过tree = defaultdict(lambda: tree()),在下一行tree['a'] 导致错误:TypeError: 'collections.defaultdict' object is not callable`
  • 您仍然需要外部lambda 来使tree 成为一个函数,而不是单个defaultdict 对象。所以tree = lambda: defaultdict(tree) 有效,tree = lambda: defaultdict(lambda: tree()) 也有效。 treedefaultdict 的每个参数都需要可调用
  • @Samwise 明白了,谢谢!由于lambda: tree() 等价于tree,这意味着更长的tree = lambda: defaultdict(lambda: tree()) 等价于tree = lambda defaultdict(tree)

标签: python tree nested trie recursive-datastructures


【解决方案1】:

这里:

tree = lambda: defaultdict(tree)

tree是一个函数,每次执行都会创建一个defaultdict。再次调用tree会给出defaultdict的默认值,每次都会创建一个新的defaultdict。


这里:

tree = defaultdict(lambda: tree)

tree 是一个特定的默认字典。 defaultdict 的默认值由返回tree 的函数给出,该函数与特定的defaultdict 相同。所以字典的默认值就是它自己。

【讨论】:

  • 谢谢!我现在明白了!所以用第二个。当我第一次做tree['a']时,最初,tree没有'a'键,所以它有'tree['a'] = (lambda: tree)() = tree. So after doing tree['a'] , tree` 看起来像 {'a': tree}。如果我再做tree['b']['c'],它基本上会做(tree['b'])['c'] = (tree)['c] = tree,所以现在'tree`看起来像{'a': tree, 'b': tree, 'c': tree}
猜你喜欢
  • 2013-10-11
  • 2012-01-15
  • 1970-01-01
  • 1970-01-01
  • 2017-03-02
相关资源
最近更新 更多