为何Python中两行功能看似等价的代码运行结果存在差异?
为什么
dict0[villagers[j]].add(i)会更新字典中多个集合? 问题出在你代码的else分支赋值逻辑,以及两种集合操作的本质差异:
1. 多个字典键共享同一个集合对象
看else分支的代码:
union_set = set() for j in range(k): union_set |= dict0[villagers[j]] for j in range(k): dict0[villagers[j]] = union_set
这里你把同一个union_set对象,赋值给了当前villagers列表里所有元素对应的字典值。比如处理示例输入的第二行2 5 6时,dict0[5]和dict0[6]会指向同一个集合对象——它们不是两个独立的集合,只是同一个集合的两个引用。
2. 两种操作的本质差异
dict0[villagers[j]] = dict0[villagers[j]] | set([i]):|是集合的并集操作,它会返回一个全新的集合对象,然后你把这个新集合重新赋值给字典的键。这一步会打破之前的共享引用——该键现在指向独立的新集合,和其他键的集合不再关联。dict0[villagers[j]].add(i):add()是直接在原集合对象上进行修改。如果多个字典键指向同一个集合对象,那么修改这个对象时,所有指向它的键对应的集合都会同步变化——因为它们本质上是同一个东西。
3. 极简示例验证
用一段简单代码就能看清楚这个区别:
# 多个键指向同一个集合 s = set() d = {'a': s, 'b': s} # 用add修改 d['a'].add(1) print(d['b']) # 输出 {1},因为a和b指向同一个集合 # 用并集赋值修改 d['a'] = d['a'] | {2} print(d['b']) # 输出 {1},因为a现在指向新集合,b还是原来的
回到你的代码场景
当处理包含1的村民组时,如果之前某些村民已经通过else分支共享了同一个集合对象,那么调用add(i)修改其中一个时,所有共享该对象的村民集合都会被更新。而用|生成新集合赋值的方式,会让每个村民的集合变成独立个体,修改时不会互相影响。
内容的提问来源于stack exchange,提问作者empshock
相关产品推荐
相关产品推荐

