Python字典实现Trie时node=node[c]的执行逻辑与打印结果疑问
Trie字典实现的引用逻辑与打印结果对应拆解
核心机制:node = node[c]的执行逻辑
- 类初始化时的
self.t是Trie的根字典,所有单词的路径都是以嵌套字典的形式挂在这个根容器下 - 代码里的
node只是一个临时引用标签,不是独立的字典拷贝:- 进入
insert方法时,先把node标签贴到根字典self.t上 - 每执行一次
node = node[c],只是把这个临时标签从当前字典,移动指向当前字典中键c对应的子字典对象,全程没有复制任何数据 - 所有对
node的修改(比如新建键值对、加结束标记),都是直接修改内存中对应的实际字典对象,这也是多层嵌套字典能逐层挂载的核心原因
- 进入
- 循环走完单词所有字符后执行的
node['-'] = True,本质是在当前走到的最内层字典上打一个标记,说明从根节点到这里的路径是一个完整的单词。
逐流程对照打印输出
三次插入操作累计产生15次循环内的print(node),和你给出的输出完全一一对应:
第一次插入:insert("word")
单词长度为4个字符,对应4次打印,此时根字典为空:
- 处理字符
w:根字典中不存在w,新建空字典作为w的对应值,node标签移动指向这个新建的空字典,打印{}(对应输出第1行) - 处理字符
o:当前w对应的子字典中不存在o,新建空字典作为o的对应值,node标签移动指向这个新建的空字典,打印{}(对应输出第2行) - 处理字符
r:当前o对应的子字典中不存在r,新建空字典作为r的对应值,node标签移动指向这个新建的空字典,打印{}(对应输出第3行) - 处理字符
d:当前r对应的子字典中不存在d,新建空字典作为d的对应值,node标签移动指向这个新建的空字典,打印{}(对应输出第4行)
循环走完后,在d对应的最内层字典加上'-': True的结束标记,此时根字典的完整结构为{'w': {'o': {'r': {'d': {'-': True}}}}}。
第二次插入:insert("welcome")
单词长度为7个字符,对应7次打印,此时根字典已经存在w键的历史结构:
- 处理字符
w:临时node标签重新贴到根字典上,发现根字典已经有w键,不需要新建字典,直接把标签移动指向w对应的子字典——这个子字典已经存了之前插入的o分支完整结构,打印{'o': {'r': {'d': {'-': True}}}}(对应输出第5行,也就是你看到的第一个非空字典打印) - 处理字符
e:当前w对应的子字典中不存在e,新建空字典作为e的对应值,node标签移动指向这个新建的空字典,打印{}(对应输出第6行) - 处理字符
l:当前e对应的子字典中不存在l,新建空字典作为l的对应值,node标签移动指向这个新建的空字典,打印{}(对应输出第7行) - 处理字符
c:当前l对应的子字典中不存在c,新建空字典作为c的对应值,node标签移动指向这个新建的空字典,打印{}(对应输出第8行) - 处理字符
o:当前c对应的子字典中不存在o,新建空字典作为o的对应值,node标签移动指向这个新建的空字典,打印{}(对应输出第9行) - 处理字符
m:当前o对应的子字典中不存在m,新建空字典作为m的对应值,node标签移动指向这个新建的空字典,打印{}(对应输出第10行) - 处理字符
e:当前m对应的子字典中不存在e,新建空字典作为e的对应值,node标签移动指向这个新建的空字典,打印{}(对应输出第11行)
循环走完后,在最内层e对应的字典加上'-': True的结束标记,此时w对应的子字典已经有两个分支:通向word的o分支、通向welcome的e分支。
第三次插入:insert("what")
单词长度为4个字符,对应4次打印:
- 处理字符
w:临时node标签重新贴到根字典上,发现根字典已经有w键,直接把标签移动指向w对应的子字典——此时这个子字典已经存了o分支和刚建完的e分支的完整结构,打印{'o': {'r': {'d': {'-': True}}}, 'e': {'l': {'c': {'o': {'m': {'e': {'-': True}}}}}}(对应输出第12行,也就是你看到的第二个长非空字典打印) - 处理字符
h:当前w对应的子字典中不存在h,新建空字典作为h的对应值,node标签移动指向这个新建的空字典,打印{}(对应输出第13行) - 处理字符
a:当前h对应的子字典中不存在a,新建空字典作为a的对应值,node标签移动指向这个新建的空字典,打印{}(对应输出第14行) - 处理字符
t:当前a对应的子字典中不存在t,新建空字典作为t的对应值,node标签移动指向这个新建的空字典,打印{}(对应输出第15行)
循环走完后,在最内层t对应的字典加上'-': True的结束标记,整个插入流程结束。
为什么会出现非空的打印结果
很多人会疑惑为啥打印不全是空字典,核心原因是:
- 当你走到某条路径的节点时,如果这个节点已经被之前的插入操作构建过部分分支,此时
node指向的就不是刚新建的空字典,而是已经存了其他路径数据的旧字典,打印自然不是空的。 - 三次插入中,只有三次走到
w节点的位置:第一次走到时w对应的子字典是空的,打印{};第二次走到时w下面已经有o分支,打印带o的嵌套字典;第三次走到时w下面已经有o、e两个分支,打印更长的嵌套字典。其余所有打印都是第一次走到对应位置,新建的子字典自然是空的,打印就是{}。
内容的提问来源于stack exchange,提问作者yy_yan
相关产品推荐
相关产品推荐

