Python中set.intersection()是获取交集的标准方法,返回新集合且支持多参数和任意可迭代对象;JavaScript需手写filter+has实现,注意性能与类型安全。

Python 的 set.intersection() 最常用也最直观
直接调用 intersection() 是获取两个(或多个)set 交集的标准方式,它返回一个新集合,不修改原集合。
常见错误是误以为必须传入列表或元组——其实只接受可迭代对象,但内部会自动转换为集合;如果传入非集合类型(如字符串、字典),行为可能不符合直觉(比如 {1,2,3}.intersection("ab") 返回空集,因为字符串被当作了字符迭代器)。
- 支持多个参数:
s1.intersection(s2, s3, s4)等价于s1 & s2 & s3 & s4 - 参数可以是任意可迭代对象,例如
s.intersection([2,3,4])或s.intersection(range(5)) - 性能上,推荐把最小的集合放在调用方位置(即
small_set.intersection(large_iterable)),内部会优化遍历顺序
JavaScript 没有原生 intersection,得靠 filter + has
ES6 的 Set 不提供 intersection 方法,必须手写。最稳妥的做法是把第二个集合转成 Set 再用 filter:
const a = new Set([1, 2, 3, 4]);
const b = new Set([3, 4, 5, 6]);
const intersection = new Set([...a].filter(x => b.has(x))); // Set {3, 4}
容易踩的坑:直接用 Array.prototype.filter 但没把 b 转成 Set(比如用 arrB.includes(x)),会导致时间复杂度从 O(n) 升到 O(n×m),尤其当 b 很大时明显卡顿。
- 若需复用,可封装为函数:
const intersect = (a, b) => new Set([...a].filter(x => b.has(x))) - 注意:传入的
a和b必须是Set实例;若不确定,先用new Set(input)安全兜底
别混淆 & 运算符和 intersection() 的返回类型差异
在 Python 中,& 和 intersection() 行为一致,但类型推断和 IDE 支持可能不同;更重要的是,& 只能用于两个 set,而 intersection() 可接任意多个参数或可迭代对象。
典型误用场景:想对一个 set 和一个 list 求交,写了 s & [1,2,3] ——这会直接抛出 TypeError: unsupported operand type(s) for &: 'set' and 'list'。
- 正确写法只有:
s.intersection([1,2,3])或s & set([1,2,3]) -
intersection()内部会尝试调用参数的__iter__,失败才报错;&则严格要求双方都是set - 使用
typing注解时,intersection()更易表达泛型意图(如Set[T].intersection(Iterable[T]) → Set[T])
当元素不可哈希时,intersection 失效,得换思路
set 要求元素可哈希,所以包含字典、列表等可变类型的嵌套结构无法直接参与 intersection。此时不能硬转 set,否则报 TypeError: unhashable type。
真实场景比如处理 API 返回的 JSON 列表,每个元素是字典,需要按某个字段(如 "id")取交集。
- 先提取关键字段生成哈希集合:
ids_a = {d["id"] for d in list_a},再过滤:[d for d in list_b if d["id"] in ids_a] - 若需完整对象交集且字段不唯一,得用
frozenset包装可哈希版本(如frozenset(d.items())),但要注意键序问题(Python 3.7+ 字典保持插入序,但不保证跨环境一致) - 这种情况下,别强行套用
intersection(),逻辑清晰比代码短更重要
set,再决定走内置方法还是手动过滤;不可哈希的情况,提前抽特征比事后调试强得多。

















