在查看here以查找如何在python中创建trie时,我的问题出现了。以下代码在最高投票的答案中给出:
>>> _end = '_end_'
>>>
>>> def make_trie(*words):
... root = dict()
... for word in words:
... current_dict = root
... for letter in word:
... current_dict = current_dict.setdefault(letter, {})
... current_dict[_end] = _end
... return root
...
>>> make_trie('foo', 'bar', 'baz', 'barz')
{'b': {'a': {'r': {'_end_': '_end_', 'z': {'_end_': '_end_'}},
'z': {'_end_': '_end_'}}}, 'f': {'o': {'o': {'_end_': '_end_'}}}}
我不明白“current_dict = root”行的用途是什么;似乎删除该行并用root替换所有current_dict将做同样的事情。 (同样的想法在this reply表达,但没有回答。)我知道这实际上不起作用,因为我尝试了它并返回一个空字典。
我还尝试将print语句放在第二个for循环中,以查看current_dict和root是如何更新的。我认为既然它们被设置为相同,它们会引用相同的字典并同时更新,但事实并非如此。
显然,我对这种互动有一个根本的误解。帮助
答案 0 :(得分:0)
您必须为每个单词重置current_dict = root
,因为如果密钥已在dict中,current_dict = current_dict.setdefault(letter, {})
将current_dict
设置为新的空字典或root的现有子字典。
dict.setdefault(k, d)
有点棘手,因为它同时做了两件事。它的工作方式与dict.get
类似,如果存在,则返回键k
的值,否则返回默认值d
。如果密钥不存在,它还会将d
作为值插入。
所以,正如你所看到的,current_dict
并不总是根词典,但是当你迭代单词中的字母时,也会引用子词,你必须将它重置为{{ 1}}再次从顶层开始。