You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

为何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

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.28 00:02:41