【发布时间】:2021-08-21 01:43:28
【问题描述】:
如以下两个代码sn-ps所示,链式赋值的顺序很重要(即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和node[ch]指向同一个dict 实例,还是希望它们各自有一个单独的dict?当您拥有a = b = {}时,只会创建一个新字典。 -
我怀疑使用
defaultdict在您的用例中可能很有意义,因为您的目标是能够简洁地定义嵌套字典。 -
def dict_of_dicts(): return collections.defaultdict(dict_of_dicts)表示如果您指定trie = dict_of_dicts(),那么您可以运行trie['a']['b']['c'] = {},而无需事先初始化trie['a']或trie['a']['b']。 -
@CharlesDuffy 谢谢!我想要第二个链式分配的行为。 (抱歉回复晚了。)