python中set去重比list快,因set基于哈希表实现o(1)查找,而list需o(n)线性扫描,整体去重达o(n²);保序推荐dict.fromkeys(lst)或集合辅助推导式,均保持o(n)复杂度。

Python 中用 set 去重比用 list 去重快得多,核心原因是底层实现不同:set 基于哈希表,平均查找/插入时间复杂度为 O(1);list 是线性结构,每次检查是否已存在都要遍历,最坏 O(n),整体去重接近 O(n²)。
为什么 list 去重慢?
常见 list 去重写法如 [x for i, x in enumerate(lst) if x not in lst[:i]] 或手动遍历 + 判断,本质是每遇到一个新元素,都要在已有结果中逐个比较。数据量稍大(比如上万条),耗时会明显上升。
- 每次
x not in result_list都是线性扫描 - 列表越长,后续每次判断越慢
- 内存上虽不额外开销,但时间成本不可忽视
set 去重为什么快?
list(set(lst)) 是最简方式,依赖 set 的自动排重特性。set 插入时通过哈希值快速定位,冲突少时几乎常数时间完成。即使考虑哈希计算和去序问题,总时间仍稳定在 O(n) 级别。
- 插入、查重都是平均 O(1)
- 一次性遍历原列表即可完成去重
- 适合大多数不要求顺序的场景
保留顺序时怎么兼顾性能?
若需保持首次出现顺序,直接用 set 会打乱顺序,但不必退回到纯 list 方案。推荐用 dict.fromkeys(lst)(Python 3.7+ 保证插入序)或集合辅助的循环:
立即学习“Python免费学习笔记(深入)”;
-
list(dict.fromkeys(lst))—— 简洁、高效、保序、原生支持 - 手动方式:
seen = set(); [x for x in lst if not (x in seen or seen.add(x))]—— 利用 set 快速查重,同时用列表推导保序
这两种都维持了 O(n) 时间复杂度,远优于纯 list 方案。
实际性能差距有多大?
在 10 万整数的测试中(无重复):
-
list(set(lst)):约 2–3 毫秒 -
dict.fromkeys(lst):约 4–6 毫秒 - 纯 list 循环去重(
if x not in res: res.append(x)):超过 1000 毫秒,慢两个数量级
数据越长,差距越显著;尤其含大量重复时,list 方案的内层扫描次数会爆炸式增长。











