it编程 > 前端脚本 > Python

Python实现List列表去重的五种方案

7人参与 2025-12-12 Python

一、看似简单的去重,藏着百万级效率差距

列表去重是python开发的高频需求,但多数开发者只停留在list(set(lst))的表层用法。殊不知在数据量放大到10万、100万级时,不同方案的效率差异可达100倍以上——曾遇到过同事用列表推导式处理100万条日志去重,耗时12分钟,换成set后仅需0.3秒。

二、底层原理拆解:为什么这些方法是最优解?

1. 核心去重方案的底层逻辑

方法底层实现时间复杂度核心依赖
set(lst)哈希表(hash table)o(n)python内置类型,c语言实现
dict.fromkeys(lst)字典键唯一性(3.7+保序)o(n)字典插入顺序保留特性
列表推导式+in判断线性查找o(n²)列表原生索引机制
pandas.series.drop_duplicates()哈希表+向量化运算o(n)pandas库(基于numpy)
sorted(list(groupby(lst)))排序+分组o(n log n)itertools模块

2. 关键原理深挖

三、实测数据对比:不同数据量下的最优选择

1. 测试环境说明

2. 效率实测结果(单位:秒)

方法1万条数据10万条数据100万条数据保序性支持复杂过滤
set(lst)0.00080.0030.028
list(dict.fromkeys(lst))0.00120.0050.042
列表推导式[x for x in lst if x not in new_lst]0.1211.81203.5
pd.series(lst).drop_duplicates().tolist()0.0040.0120.095
sorted(list(groupby(lst)))0.0030.0350.41

3. 数据交叉验证

四、工程案例落地:从12分钟到0.3秒的优化实践

案例1:日志数据去重(100万条请求id)

# 低效代码(12分钟耗时)
logs = [str(random.randint(1, 500000)) for _ in range(1000000)]
unique_logs = []
for log in logs:
    if log not in unique_logs:  # 每次判断都是o(n)查找
        unique_logs.append(log)
# 优化后代码(0.3秒耗时)
unique_logs = list(dict.fromkeys(logs))  # o(n)时间复杂度

案例2:大数据量薪资数据去重(含条件过滤)

import pandas as pd
# 读取数据(避免excel崩溃问题)
df = pd.read_csv("salary_data.csv", low_memory=false)
# 去重+条件过滤(1.2秒完成)
unique_salary = df.drop_duplicates(
    subset=["employee_id", "salary_date"],  # 按员工id+薪资日期去重
    keep="last"  # 保留最后一条记录
).query("salary > 10000")  # 过滤高薪数据

五、常见坑点与trouble shooting(5大高频问题)

坑点1:set去重打乱原列表顺序

# 保序去重最优解(3.7+)
unique_lst = list(dict.fromkeys(lst))
# 兼容低版本(3.6-)
from collections import ordereddict
unique_lst = list(ordereddict.fromkeys(lst))

坑点2:不可哈希元素导致报错

def deduplicate_unhashable(lst, key_func=none):
    """处理不可哈希元素的去重"""
    seen = set()
    result = []
    for item in lst:
        # 用自定义key函数提取可哈希特征
        key = key_func(item) if key_func else str(item)
        if key not in seen:
            seen.add(key)
            result.append(item)
    return result
# 示例:去重包含字典的列表
lst = [{"id":1}, {"id":2}, {"id":1}]
unique_lst = deduplicate_unhashable(lst, key_func=lambda x: x["id"])

坑点3:pandas处理nan的一致性问题

import pandas as pd
import numpy as np
lst = [1, 2, np.nan, 2, np.nan]
# 统一处理逻辑:将nan视为重复
unique_lst = pd.series(lst).drop_duplicates(keep="first").tolist()

坑点4:大列表用列表推导式去重

坑点5:dict.fromkeys()在低版本python不保序

六、进阶思考:去重方案的选型决策树

1. 选型核心逻辑

graph td
a[需求场景] --> b{是否保序}
b -->|否| c{数据量}
b -->|是| d{数据量}
c -->|≤1万| e[set(lst) 简洁优先]
c -->|>1万| f[set(lst) 效率优先]
d -->|≤10万| g[dict.fromkeys(lst) 原生无依赖]
d -->|>10万| h{是否需要复杂过滤}
h -->|是| i[pandas.drop_duplicates() 功能优先]
h -->|否| j[dict.fromkeys(lst) 效率优先]

2. 未来优化方向

七、总结:记住这3个核心结论

  1. 小数据量(≤1万条):无需纠结,保序用dict.fromkeys(),无序用set(),代码简洁优先;
  2. 中大数据量(>10万条):保序选dict.fromkeys(),需过滤选pandas,避免任何o(n²)方案;
  3. 避坑关键:先明确是否保序、是否含不可哈希元素、数据量量级,再选型——多数性能问题都是“用错场景”导致的。

以上就是python对list列表去重的五种方案的详细内容,更多关于python list列表去重的资料请关注代码网其它相关文章!

(0)

您想发表意见!!点此发布评论

推荐阅读

Python判断字符串是否包含特定子串的7种方法

12-12

Python自动化办公全攻略之Excel/Word/PDF/邮件批量处理

12-12

Python自动解析markdown中的图片并保存

12-12

Python获取字符串最后一个字符的多种方法

12-12

Python可变默认参数陷阱案例和解决方案

12-12

Python使用Playwright实现更快更现代的浏览器自动化实战指南

12-12

猜你喜欢

版权声明:本文内容由互联网用户贡献,该文观点仅代表作者本人。本站仅提供信息存储服务,不拥有所有权,不承担相关法律责任。 如发现本站有涉嫌抄袭侵权/违法违规的内容, 请发送邮件至 2386932994@qq.com 举报,一经查实将立刻删除。

发表评论