为什么顺序在这个链式分配中很重要?

Why does the order matter in this chained assignment?

如以下两个代码片段所示,链式赋值的顺序很重要(即 node = node[ch] = {} 不等同于 node[ch] = node = {}

trie = {}
node = trie
for ch in "word":
    if ch in node:
        node = node[ch]
    else:
        node = node[ch] = {} # chained assignment #1
print(trie) # {}
trie = {}
node = trie
for ch in "word":
    if ch in node:
        node = node[ch]
    else:
        node[ch] = node = {} # chained assignment #2
print(trie) # {'w': {'o': {'r': {'d': {}}}}}

为什么顺序很重要?


根据another SO question,链式赋值

a = b = c

相当于:

tmp = c
a = c
b = c

并且我验证了等效的形式产生了相同的行为。即

        # node = node[ch] = {} # chained assignment #1
        tmp = {}
        node = tmp
        node[ch] = tmp

导致 print(trie){}

同时

        node[ch] = node = {} # chained assignment #2
        tmp = {}
        node[ch] = tmp
        node = tmp

导致 print(trie){'w': {'o': {'r': {'d': {}}}}}

最后基本回答了你的问题

node = tmp
node[ch] = tmp

node[ch] = tmp
node = tmp

不等价。一旦执行 node = tmp,就会丢失 node 之前的内容,并用新的字典替换它们。这意味着在第一种情况下,您会立即在循环内丢失对 trie 的引用,并且无法再对其进行变异。在第二种情况下,您 更改旧结果 ,然后将 node 重新分配给新词典。