保序去重不能用set(),应使用dict.fromkeys();因set()无序导致日志、行为序列等场景出错,而python 3.7+字典保序,dict.fromkeys()兼具唯一性与顺序性,简洁可靠。

去重必须保序?别直接用 set(),改用 dict.fromkeys()
直接 list(set(data)) 虽快,但顺序全乱——日志去重、用户行为序列、URL列表等场景下,这等于引入数据错误。Python 3.7+ 的字典天然保序,dict.fromkeys() 利用键唯一性+插入顺序,是目前最简、最稳的保序去重方案。
-
list(dict.fromkeys([1, 2, 2, 3, 1]))→[1, 2, 3],原序保留,无额外依赖 - 老版本(seen = set() + 列表推导,但代码变长、易出错
- 别试图用
sorted(set(data), key=data.index):对百万级数据,data.index每次都是 O(n),整体退化成 O(n²)
交集运算选 & 还是 intersection()?看输入类型
符号运算符 & 看似简洁,但只认 set 类型;而 intersection() 方法能“宽容”地接受任意可迭代对象,比如列表、元组甚至生成器。
图片提示词生成器?不止如此。 马甲系统 —— 把脑海中的画面,翻译成AI能理解的专业表达。 用得越多,它越懂你:首次需要多问几句确认方向,用久了几乎一说就懂。 用得越多,它越快:缓存机制让后续对话越来越省。 RAG进化:成功案例持续入库,越跑越聪明。 输入「新手指南」查看完整功能介绍
- 如果两个变量确定是
set,用a & b & c更直观,性能略优 - 如果其中一个是
list(如从 API 返回的 JSON 数组),a.intersection(b)可直接运行;a & b会抛TypeError: unsupported operand type(s) - 多个动态集合参与交集时,
allowed_types.intersection(*user_inputs)比拼接&更安全、更易读
含不可哈希元素(如字典、列表)怎么办?先转再塞
set([{'id': 1}, {'id': 1}]) 必报 TypeError: unhashable type: 'dict'——集合底层靠哈希定位,而 dict/list 是可变类型,天生不可哈希。
- 简单结构(如固定字段的字典):用
tuple(d.items())转成元组,再进集合:{tuple(d.items()) for d in data} - 嵌套深或类型混杂:用
json.dumps(d, sort_keys=True)序列化为字符串(注意浮点精度、NaN会变成null) - 别图省事用
frozenset包 list ——语义错位(你不是想存“不可变集合”,而是想存“可哈希的 list 表示”),且frozenset([1,2]) != frozenset([2,1]),顺序敏感时结果不可控
处理千万级数据时,内存和速度怎么平衡?
把一千万条字符串全 load 进内存再 set(),可能瞬间吃光 4GB 内存;但逐行判断又慢。折中方案是流式去重 + 分块哈希缓存。
- 用生成器 +
seen集合边读边 yield,适合单次扫描场景 - 若需多次交集(如比对多个大文件),优先将小集合转
set,大集合用生成器逐条检查:if line in small_set:——查set是 O(1),比遍历大列表快几个数量级 - 真到亿级,就得上
bitarray或布隆过滤器(Bloom Filter),但 Python 原生set在千万级内仍是性价比最高的选择
Python免费学习笔记(深入):立即使用
在学习笔记中,你将探索 Python 的核心概念和高级技巧!










