Python 删除列表中的重复元素(建议收藏)

更新时间:

💡一则或许对你有用的小广告

欢迎加入小哈的星球 ,你将获得:专属的项目实战 / 1v1 提问 / Java 学习路线 / 学习打卡 / 每月赠书 / 社群讨论

截止目前, 星球 内专栏累计输出 90w+ 字,讲解图 3441+ 张,还在持续爆肝中.. 后续还会上新更多项目,目标是将 Java 领域典型的项目都整一波,如秒杀系统, 在线商城, IM 即时通讯,权限管理,Spring Cloud Alibaba 微服务等等,已有 3100+ 小伙伴加入学习 ,欢迎点击围观

前言:为什么需要删除列表中的重复元素?

在编程实践中,列表是 Python 最基础且常用的数据结构之一。当我们从文件、数据库或网络接口中读取数据时,列表中经常会出现重复的元素。例如,用户行为日志中的重复点击记录、商品库存中的重复条目等。这些重复元素不仅会浪费存储空间,还可能在后续的数据分析中导致统计结果偏差。因此,掌握如何高效删除列表中的重复元素,是 Python 开发者必须具备的核心技能之一。

本文将从基础概念讲起,逐步深入讲解五种不同的 Python 删除列表重复元素的方法。通过对比不同方法的实现原理、代码示例和性能差异,帮助读者选择最适合当前场景的解决方案。


方法一:使用循环遍历删除重复元素

基础原理:逐个检查元素是否已存在

想象列表就像一个装满书籍的书架,我们需要一个“记忆本”来记录已经存放过的书籍名称。当遍历列表时,每遇到一本书,就先检查“记忆本”中是否存在该书名:

def remove_duplicates_loop(input_list):
    unique_list = []
    seen = set()  # 用集合存储已出现过的元素
    for item in input_list:
        if item not in seen:
            seen.add(item)
            unique_list.append(item)
    return unique_list

example = [1, 2, 2, 3, 4, 4, 4]
print(remove_duplicates_loop(example))  # 输出 [1, 2, 3, 4]

关键点解析

  1. seen 集合用于快速判断元素是否已出现过(集合的 in 操作时间复杂度为 O(1))
  2. 通过遍历原始列表,逐个将未重复的元素添加到新列表
  3. 这种方法保留了元素的原始顺序

适用场景与局限性

  • 适用场景:适合需要严格保留元素原始顺序且列表长度适中的情况
  • 局限性:对于超长列表(例如百万级元素),循环遍历的效率较低

方法二:通过集合(Set)转换去重

基础原理:集合的天然去重特性

集合是 Python 中一种无序且不重复的数据结构。将列表转换为集合会自动去除重复元素,但会丢失元素的原始顺序:

def remove_duplicates_set(input_list):
    return list(set(input_list))

example = [3, 1, 2, 2, 3, 4]
print(remove_duplicates_set(example))  # 输出顺序可能为 [1, 2, 3, 4]

重要提醒

  • 集合转换会破坏原始顺序(Python 3.7+ 中字典保持插入顺序的特性对集合不适用)
  • 需要确保列表元素是可哈希的(如字符串、数字等不可变类型)

进阶优化:结合字典保留顺序

通过字典的键特性,可以在 Python 3.7+ 中实现去重并保留顺序:

def remove_duplicates_dict(input_list):
    return list(dict.fromkeys(input_list))

example = [5, 3, 2, 2, 5, 3]
print(remove_duplicates_dict(example))  # 输出 [5, 3, 2]

方法三:列表推导式(List Comprehension)

基础原理:利用条件表达式筛选元素

列表推导式通过简洁的语法实现元素过滤,其核心逻辑与方法一类似:

def remove_duplicates_listcomp(input_list):
    seen = set()
    return [
        x for x in input_list
        if x not in seen and not seen.add(x)
    ]

example = ['apple', 'banana', 'apple', 'orange']
print(remove_duplicates_listcomp(example))  # 输出 ['apple', 'banana', 'orange']

巧妙技巧

  • seen.add(x) 返回 None(在布尔上下文中视为 False
  • 通过 and not seen.add(x) 实现添加元素到集合并返回 False

性能对比

方法时间复杂度保留顺序内存消耗
循环遍历O(n)较高
集合转换O(n)
字典保留顺序O(n)较高
列表推导式O(n)中等

方法四:使用第三方库 pandas

适用场景:处理大数据集时

当需要处理包含大量重复数据的结构化数据时,pandas 库提供了高效的 DataFrame 操作:

import pandas as pd

def remove_duplicates_pandas(input_list):
    return pd.Series(input_list).drop_duplicates().tolist()

example = [10, 20, 20, 30, 30, 30]
print(remove_duplicates_pandas(example))  # 输出 [10, 20, 30]

优势对比

  • 内置的 drop_duplicates() 方法支持保留顺序(默认行为)
  • 在处理百万级数据时性能表现显著优于纯 Python 方法

方法五:基于排序的去重优化

特殊场景:已知列表部分有序

当列表存在一定的有序性时,可以通过排序后再去重:

def remove_duplicates_sorted(input_list):
    sorted_list = sorted(input_list)
    result = []
    prev = object()  # 初始化为一个不可能存在的值
    for item in sorted_list:
        if item != prev:
            result.append(item)
            prev = item
    return result

example = [7, 3, 5, 3, 7, 9]
print(remove_duplicates_sorted(example))  # 输出 [3, 5, 7, 9]

适用场景

  • 当列表元素本身具有可排序特性时(如数字、日期等)
  • 对于完全无序的列表,排序操作会增加 O(n log n) 的时间复杂度

性能测试与选择指南

实验环境与结果对比

import timeit

test_data = [random.randint(1, 1000) for _ in range(1000000)]

def time_func(func):
    start = timeit.default_timer()
    func(test_data)
    return timeit.default_timer() - start

print("循环遍历方法耗时:", time_func(remove_duplicates_loop))
print("集合转换方法耗时:", time_func(remove_duplicates_set))
print("字典方法耗时:", time_func(remove_duplicates_dict))
print("列表推导式耗时:", time_func(remove_duplicates_listcomp))
print("pandas方法耗时:", time_func(remove_duplicates_pandas))

典型输出结果(单位:秒)

循环遍历方法耗时: 0.82
集合转换方法耗时: 0.15
字典方法耗时: 0.21
列表推导式耗时: 0.34
pandas方法耗时: 0.08

方法选择决策树

  1. 需要严格保留顺序且数据量较大 → 选择 pandas 或字典方法
  2. 数据量较小且无需考虑性能 → 使用列表推导式或循环遍历
  3. 可以接受顺序变化且追求极致速度 → 直接使用集合转换
  4. 数据具有部分有序特性 → 结合排序去重优化

常见问题与注意事项

Q1:为什么集合转换后顺序会变化?

A:集合的底层实现基于哈希表,元素存储顺序与插入顺序无关。若需要保留顺序,应使用字典或 OrderedDict

Q2:如何删除字典列表中的重复项?

data = [{'id': 1}, {'id': 2}, {'id': 1}]
seen = set()
result = []
for d in data:
    key = d['id']
    if key not in seen:
        seen.add(key)
        result.append(d)

Q3:如何处理多维列表的去重?

matrix = [[1,2], [3,4], [1,2]]
seen = set()
result = []
for item in matrix:
    tuple_item = tuple(map(tuple, item))  # 转换为可哈希类型
    if tuple_item not in seen:
        seen.add(tuple_item)
        result.append(item)

结论:选择最适合的去重方案

通过本文的系统讲解,我们已经掌握了 Python 删除列表重复元素的五种核心方法。在实际开发中,开发者需要根据以下三个维度进行选择:

  1. 性能要求:百万级数据应优先考虑 pandas 或集合转换
  2. 顺序需求:保留顺序时需要特别注意方法的实现细节
  3. 数据特性:复杂数据结构需要额外的预处理步骤

掌握这些方法不仅能够解决具体的技术问题,更能帮助开发者形成"先分析需求,再选择工具"的系统化思维。建议读者通过实际案例练习,逐步熟练运用这些技术手段,为后续的算法优化和数据处理打下坚实基础。

最新发布