python中set.union()默认去重合并,不保留顺序;支持多可迭代参数但要求元素可哈希,不可哈希类型会报错;与|运算符语义相同但更灵活,二者均返回新集合。

union 方法在 Python set 中的默认行为就是去重合并
Python 的 set.union() 本身不保留插入顺序,也不报错,它天然忽略重复元素——这不是“额外处理”,而是集合(set)的数据结构特性决定的。只要所有参与合并的对象都是 set,调用 union() 就自动完成去重。
常见错误现象:TypeError: unhashable type: 'list',这是因为传入了列表、字典等不可哈希类型;或者误把 list.union() 当成通用方法(列表没有 union)。
- 只接受可迭代对象,但内部会尝试将每个元素转为 hashable 类型;非 hashable 元素(如
[1,2]、{'a':1})会直接报错 - 支持多个参数:
set1.union(set2, set3, set4),比链式set1 | set2 | set3更清晰 - 空集合参与不影响结果:
set().union({1,2}, {2,3})→{1, 2, 3}
union 和 | 操作符的区别不只是写法
| 是集合的并集运算符,语义和 union() 完全一致,但行为上有个关键差异:运算符只支持 set 类型,而 union() 可以接受任意可迭代对象(如 list、tuple、str),只要其元素可哈希。
例如:{1, 2}.union([2, 3, 4]) 合法,返回 {1, 2, 3, 4};但 {1, 2} | [2, 3, 4] 会抛出 TypeError。
- 用
union()更灵活,尤其当输入来源不确定(比如函数返回的是 list)时 - 用
|更快一点点(C 层实现优化),但差异微乎其微,无需刻意选择 - 二者都不修改原集合,始终返回新
set
合并含嵌套结构或自定义对象时 union 会失效
union() 要求所有元素可哈希,所以包含 list、dict、set 的混合数据无法直接进集合。例如 {[1,2], [3,4]} 语法错误;{1, (2,3), {'a':1}} 中字典部分也会报错。
此时不能依赖 union() 自动去重,必须先做转换或定义逻辑:
- 把嵌套结构序列化:
json.dumps(item, sort_keys=True)后再进 set,适合纯 JSON 可表示的数据 - 对自定义类,实现
__hash__和__eq__,确保相等对象有相同 hash 值 - 用
dict.fromkeys(iterable)模拟去重(适用于可迭代但不可哈希的序列,如字符串列表),但不等价于集合语义
JavaScript 里没有原生 set.union,得自己封装
ES6 的 Set 没有 union 方法,常见错误是查文档没找到就放弃,或误用数组的 concat + filter 导致性能差。
正确做法是用展开运算符加构造函数:new Set([...setA, ...setB, ...setC])。这行代码等效于 Python 的 union,且自动去重。
- 不要写
Array.from(setA).concat(Array.from(setB)).filter(...),O(n²) 时间复杂度 - 如果要兼容旧环境,可用
setA.forEach(x => setB.add(x))原地合并,但会修改setB - 注意:
Set的迭代顺序是插入顺序,所以[...setA, ...setB]中setA的元素总在前面










