As shown by the following two code snippets, the order of the chained assignment matters (i.e. node = node[ch] = {}
is not equivalent to 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': {}}}}}
Why does the order matter?
According to another SO question, the chained assignment
a = b = c
is equivalent to:
tmp = c
a = c
b = c
and I verified that the equivalent forms produced the same behavior. I.e.
# node = node[ch] = {} # chained assignment #1
tmp = {}
node = tmp
node[ch] = tmp
leads to a print(trie)
of {}
.
Meanwhile
node[ch] = node = {} # chained assignment #2
tmp = {}
node[ch] = tmp
node = tmp
leads to a print(trie)
of {'w': {'o': {'r': {'d': {}}}}}
.
You basically answered your question at the end.
and
are not equivalent. As soon as you do
node = tmp
, you lose the previous contents ofnode
, and replace them with a new dict. That means that in the first case, you immediately lose the reference totrie
inside the loop, and can no longer mutate it. In the second case, you alter the old results, then reassignnode
to the new dictionary.