为啥顺序在这个链式分配中很重要?
Posted
技术标签:
【中文标题】为啥顺序在这个链式分配中很重要?【英文标题】:Why does the order matter in this chained assignment?为什么顺序在这个链式分配中很重要? 【发布时间】: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 谢谢!我想要第二个链式分配的行为。 (抱歉回复晚了。)
【参考方案1】:
你基本上在最后回答了你的问题。
node = tmp
node[ch] = tmp
和
node[ch] = tmp
node = tmp
不等价。一旦你执行node = tmp
,你就会丢失node
以前的内容,并用新的字典替换它们。这意味着在第一种情况下,您会立即丢失循环内对trie
的引用,并且不能再对其进行变异。在第二种情况下,您更改旧结果,然后将node
重新分配给新字典。
【讨论】:
以上是关于为啥顺序在这个链式分配中很重要?的主要内容,如果未能解决你的问题,请参考以下文章