python中的集合(set)给列表去重

📅 2026/8/6 10:34:55
python中的集合(set)给列表去重
使用集合set给列表去重的核心原理是利用集合的“元素唯一性”特性自动过滤重复项。但需注意直接转集合会丢失原始顺序若需保留顺序应结合字典dict.fromkeys()或辅助集合实现。以下是具体方法一、基础去重方法1. 直接转集合不保序最快原理集合天然不允许重复元素将列表转为集合会自动去重。代码示例nums unique list(set(nums)) print(unique) # 输出顺序随机**不保证原顺序**适用场景无需保留原始顺序时如统计唯一值、去重后直接排序等。性能时间复杂度O(n)是所有方法中最快的。2. 保序去重推荐方法(1) 使用dict.fromkeys()Python 3.7原理Python 3.7 的字典默认保持插入顺序用列表元素作键可同时去重并保序。代码示例nums unique list(dict.fromkeys(nums)) print(unique) # 输出**保留首次出现顺序**优势代码简洁、性能高O(n)是官方推荐的保序去重方案。(2) 辅助集合 循环通用兼容原理遍历原列表用集合记录已出现元素仅添加新元素到结果列表。代码示例nums seen set() unique [x for x in nums if x not in seen and not seen.add(x)] print(unique) # 输出适用场景需兼容旧版 Python3.7或需自定义去重逻辑时。二、关键注意事项1.元素必须可哈希集合要求元素是可哈希的不可变对象如数字、字符串、元组。不可直接处理列表/字典等可变对象需先转为可哈希类型# 错误示例列表不可哈希 # data [, , ] # list(set(data)) # 报错TypeError: unhashable type: list # 正确做法转为元组 data [, , ] unique [list(t) for t in set(tuple(x) for x in data)] print(unique) # 输出[, ]自定义对象需实现__hash__和__eq__方法。2. 顺序问题set()去重不保留顺序不同 Python 版本/运行环境结果顺序可能不同。保序方法的选择优先用dict.fromkeys()Python 3.7。旧版本可用collections.OrderedDictfrom collections import OrderedDict unique list(OrderedDict.fromkeys(nums))3. 性能对比方法是否保序时间复杂度适用场景list(set(lst))❌O(n)无需顺序速度最快list(dict.fromkeys(lst))✅O(n)需保序的常规场景循环 辅助集合✅O(n)需自定义逻辑或兼容旧版本列表推导式if x not in✅O(n²)小数据量避免用于大数据集大数据量时O(n²) 方法如列表推导式性能显著劣于 O(n) 方法。三、复杂场景处理1. 按对象属性去重场景列表元素为字典/对象需根据特定字段去重。解决方案用字段值作为唯一标识结合辅助集合data [{id: 1, name: A}, {id: 1, name: B}, {id: 2, name: C}] seen set() unique [x for x in data if x[id] not in seen and not seen.add(x[id])] print(unique) # 输出[{id: 1, name: A}, {id: 2, name: C}]2. 大数据量去重内存优化流式处理避免一次性加载全部数据。def stream_deduplicate(iterable): seen set() for item in iterable: if item not in seen: seen.add(item) yield item # 用法unique list(stream_deduplicate(large_data_stream))总结无需保序直接用list(set(original_list))速度最快。需要保序优先用list(dict.fromkeys(original_list))Python 3.7简洁高效。元素不可哈希先转换为可哈希类型如元组再用集合去重。性能关键点避免在循环中使用if x not in listO(n²)必须用集合辅助判断O(1)。以上方法均不修改原列表而是返回新列表。若需原地去重需结合切片赋值original_list[:] list(dict.fromkeys(original_list))。