在Python中更新指向同一字典的变量
在寻找如何在python中创建trie时,出现了我的问题。在投票结果最高的答案中给出了以下代码:在Python中更新指向同一字典的变量,python,dictionary,Python,Dictionary,在寻找如何在python中创建trie时,出现了我的问题。在投票结果最高的答案中给出了以下代码: >>> _end = '_end_' >>> >>> def make_trie(*words): ... root = dict() ... for word in words: ... current_dict = root ... for letter in word: ...
>>> _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替换所有当前命令也会做同样的事情。(在中表达了同样的想法,但没有回答。)我知道这实际上不起作用,因为我尝试了,结果返回了一本空字典
我还尝试将print语句放入第二个for循环中,以查看当前的dict和root是如何更新的。我认为,由于它们被设置为相等,所以它们引用同一本词典,并将同时更新,但事实并非如此
显然,我对这种互动有一个根本性的误解。帮助?您必须为每个单词重置
current\u dict=root
,因为current\u dict=current\u dict.setdefault(字母,{})
将current\u dict
设置为新的空字典或根目录的现有子字典(如果关键字已经在dict中)
dict.setdefault(k,d)
有点棘手,因为它同时做两件事。它的工作原理与dict.get类似,并返回键k
的值(如果存在),否则返回默认值d
。如果键不存在,它也会将其插入d
作为值
因此,正如您所看到的,
current\u dict
并不总是根dict,而是在迭代单词中的字母时引用子dict,您必须将其重置为root
才能从顶层重新开始。谢谢您的回答!因此,在第二个for循环的第一次迭代之前,“current_dict=root={}”。到现在为止,一直都还不错。在第一次迭代之后,'current_dict={}'和'root={'f':{}'。这部分仍然让我困惑。我的理解是,“setdefault()”首先更改“current_dict”所指向的值(与“root”所指向的相同,这就是“root”被更新的原因),然后返回一个值,“current_dict”现在设置为指向,在本例中为“{}”'在'root'中,键为'f'。但是为什么'current_dict'不只是成为一个空字典,而不是'root'中,键为'f'的特定字典?因为“setdefault()”只返回“{}”,而不是带有键“f”的“root”中的特定“{}”,对吗?current\u dict
只是附加到对象的名称。在函数开始时,两个名称root
和current_dict
都附加到同一个“root”dict。然后,setdefault插入一个新键和空dict,并返回此空dict,并将其分配给名称current_dict
。现在,两个名称root
和current_dict
指的是不同的对象:root
仍然指的是root dict,而current_dict
指的是刚刚插入的新的空子dict。Ned Batchelder对这个主题进行了很好的讨论(如果名称/值是造成混淆的原因):