最常用且高效的方法是使用set()进行去重,适用于元素可哈希且无需保留顺序的场景;若需保留原始顺序,推荐使用dict.fromkeys()(Python 3.7+),其兼具高效性与顺序保持能力;对于不可哈希元素(如列表、字典),则只能通过遍历并逐项比较的方式实现去重,虽性能较低但通用性强。这三种方法分别对应不同需求:set适合大多数常规去重,dict.fromkeys兼顾效率与顺序,手动循环则应对复杂数据类型。性能方面,前两者平均时间复杂度为O(N),远优于第三种的O(N²)。实际应用中应根据元素类型和顺序要求选择合适方案。

在Python中对列表进行去重,最常用也最直接的方法是利用
set
当我们需要从Python列表中移除重复项时,有几种方法可以选择,每种都有其适用场景和考量。我个人在不同情境下会灵活运用它们。
1. 使用 set()
这是最简洁也通常是最高效的方法,尤其适用于列表元素都是可哈希(hashable)类型(如数字、字符串、元组)的情况。
立即学习“Python免费学习笔记(深入)”;
original_list = [1, 2, 2, 3, 4, 4, 5, 1] unique_list = list(set(original_list)) print(unique_list) # 输出: [1, 2, 3, 4, 5] (顺序可能与原列表不同)
我的看法:
set
2. 使用 dict.fromkeys()
list()
这个方法利用了字典键的唯一性。
dict.fromkeys()
None
original_list = [1, 2, 2, 3, 4, 4, 5, 1] unique_list_ordered = list(dict.fromkeys(original_list)) print(unique_list_ordered) # 输出: [1, 2, 3, 4, 5] (保留了第一次出现的顺序)
我的看法: 这个方法简直是神器!它兼顾了简洁性和效率(内部实现也依赖哈希),同时解决了
set
3. 使用循环和新列表(适用于不可哈希元素或对性能不极致要求时)
当列表包含不可哈希的元素(如其他列表、字典或自定义对象,除非你为它们实现了
__hash__
__eq__
set
dict.fromkeys
original_list = [1, 2, [3, 4], 2, [3, 4], 5]
unique_list_manual = []
for item in original_list:
if item not in unique_list_manual:
unique_list_manual.append(item)
print(unique_list_manual)
# 输出: [1, 2, [3, 4], 5] (保留了原始顺序,且适用于不可哈希元素)我的看法: 这种方法虽然看起来“笨拙”一些,但在处理复杂数据类型时却是最可靠的。它的缺点是性能可能不如基于哈希的方法,因为
item not in unique_list_manual
unique_list_manual
列表去重远不止是代码上的一个小技巧,它在实际的编程工作中扮演着至关重要的角色。从数据完整性到程序性能,再到用户体验,它的影响无处不在。我经常遇到的情况是,如果不对数据进行去重,后续的逻辑可能会变得异常复杂,甚至出现错误。
想象一下,你正在处理一份用户提交的邮件列表,如果其中有重复的地址,你发出的每一封邮件都可能被发送多次,这不仅浪费资源,还可能让用户感到困扰。或者,你在分析日志文件,统计某个事件的发生次数,如果日志中存在重复的事件记录,你的统计结果就会严重偏离真实情况。
去重能帮助我们:
在我看来,去重是数据清洗(data cleaning)的一个基本环节,就像整理房间一样,把不必要的重复物品清理掉,才能让整个空间更有效率、更整洁。
处理大型列表的去重问题,性能就成了不得不考虑的关键因素。不同的去重方法在面对海量数据时,其效率差异会非常显著。我通常会根据列表的规模和元素特性,权衡选择最合适的方案。
1. set()
2. dict.fromkeys()
set()
set
3. 循环加 in
总结和建议:
对于大多数情况,基于哈希的
set()
dict.fromkeys()
如果列表非常庞大,比如数百万甚至上亿条记录,并且内存是一个严格的限制,你可能需要考虑流式处理或者使用更专业的库(如Pandas),而不是一次性将所有数据加载到内存中去重。但对于Python内置的数据结构而言,哈希方法依然是首选。
为了验证不同方法的性能差异,我有时会使用Python的
timeit
import timeit
# 准备一个包含大量重复项的列表
list_large = [i for i in range(10000)] * 100 # 100万个元素,1万个唯一值
# 测试 set() 方法
time_set = timeit.timeit("list(set(list_large))", globals={'list_large': list_large}, number=10)
print(f"Set method: {time_set:.4f} seconds")
# 测试 dict.fromkeys() 方法
time_dict_fromkeys = timeit.timeit("list(dict.fromkeys(list_large))", globals={'list_large': list_large}, number=10)
print(f"Dict.fromkeys method: {time_dict_fromkeys:.4f} seconds")
# 测试循环加 in 检查的方法 (对于大列表会非常慢,谨慎运行)
# time_loop = timeit.timeit("""
# unique_list_manual = []
# for item in list_large:
# if item not in unique_list_manual:
# unique_list_manual.append(item)
# """, globals={'list_large': list_large}, number=1) # 只运行一次,因为太慢了
# print(f"Loop method: {time_loop:.4f} seconds")通过这样的测试,你会清晰地看到哈希方法的巨大性能优势。
在实际开发中,我们遇到的列表元素并非总是简单的数字或字符串。有时,它们可能是列表、字典或其他自定义对象,而这些类型默认是不可哈希的。同时,在某些业务场景下,列表元素的原始顺序又至关重要。这两种情况都需要我们采取更细致的去重策略。
处理不可哈希的元素:
当列表包含不可哈希的元素时,
set()
dict.fromkeys()
TypeError: unhashable type
# 包含不可哈希列表的列表
list_of_lists = [[1, 2], [3, 4], [1, 2], [5, 6], [3, 4]]
unique_list_of_lists = []
for item in list_of_lists:
if item not in unique_list_of_lists:
unique_list_of_lists.append(item)
print(unique_list_of_lists)
# 输出: [[1, 2], [3, 4], [5, 6]]这里
item not in unique_list_of_lists
__eq__
[1,2] == [1,2]
True
我的思考: 这种方法虽然性能相对较低,但却是处理复杂数据类型的“万能钥匙”。如果你自定义了类,并且希望它们可以去重,你需要确保为这些类正确实现了
__eq__
set
dict.fromkeys
__hash__
在去重时保持原始顺序:
正如前面提到的,
list(set(my_list))
list(dict.fromkeys(my_list))
original_data = ['apple', 'banana', 'apple', 'orange', 'banana', 'grape'] ordered_unique_data = list(dict.fromkeys(original_data)) print(ordered_unique_data) # 输出: ['apple', 'banana', 'orange', 'grape']
循环加 in
mixed_list = [1, 'a', [1,2], 1, 'a', {'key': 'value'}, [1,2]]
ordered_unique_mixed = []
for item in mixed_list:
if item not in ordered_unique_mixed:
ordered_unique_mixed.append(item)
print(ordered_unique_mixed)
# 输出: [1, 'a', [1, 2], {'key': 'value'}]我的经验之谈: 我不止一次地因为忽略了
set
以上就是python中怎么对列表去重?的详细内容,更多请关注php中文网其它相关文章!
python怎么学习?python怎么入门?python在哪学?python怎么学才快?不用担心,这里为大家提供了python速学教程(入门到精通),有需要的小伙伴保存下载就能学习啦!
Copyright 2014-2025 https://www.php.cn/ All Rights Reserved | php.cn | 湘ICP备2023035733号