set交集和差集最快,因基于哈希表实现,成员检查平均o(1),运算为o(min(len(s),len(t)));而list的in查找为o(n),两千万级求差集达o(n²),慢百倍以上。

用 set 做交集和差集是最快的,但前提是内存够;如果集合大到装不下,就得流式处理或用 sqlite3 临时落盘。
为什么不能直接用 list 或 dict 比较?
两个含千万级元素的 list 求差集,item in other_list 是 O(n) 查找,整体接近 O(n²),几秒变几分钟。而 set 的 in 是平均 O(1),构建后求 a - b 或 a & b 是线性扫描,实测快 100 倍以上。
-
set构建本身有开销,但只发生一次;后续多次运算可复用 - 元素必须可哈希(不能是
dict、list等),否则会报TypeError: unhashable type - 字符串、数字、tuple(不含可变项)默认可哈希;若含嵌套结构,需先转成
frozenset或json.dumps()归一化
内存不足时怎么避免 MemoryError?
当两个集合总大小远超可用 RAM(比如各 5GB 字符串),直接 set() 会崩溃。这时优先考虑分块读取 + sqlite3:
- 把一个集合写入临时表,建索引:
CREATE INDEX idx_val ON data(val) - 逐行读另一个集合,在 SQL 中用
NOT EXISTS或INNER JOIN计算差集/交集 - 避免全量加载:用
cursor.execute("SELECT val FROM data WHERE val = ?", [x])替代 Python 层查找 - 比纯 Python 流式
for x in file_a:+if x not in seen_b:快,因为 SQLite 的 B-tree 索引比 Python 的磁盘文件遍历高效得多
set.difference() 和 - 运算符有啥区别?
没本质区别,a - b 就是 a.difference(b) 的语法糖;但要注意参数类型和顺序:
-
a.difference(b, c)支持多个参数,等价于a - b - c;而-只支持二元操作 -
a.difference()返回新set,不修改a;a.difference_update(b)才原地修改 - 如果
b是任意可迭代对象(如list,generator),两者都接受;但传dict时,默认用 key 比较,不是 value - 性能上无差异,选哪个纯看可读性——多集合差集用
.difference()更清晰
真正卡住人的往往不是算法,而是数据预处理:去空格、大小写归一、编码不一致导致看似相同的字符串实际字节不同。别急着优化集合操作,先 repr() 几个样本看看真实值。
Python免费学习笔记(深入):立即使用
在学习笔记中,你将探索 Python 的核心概念和高级技巧!











