Python列表去重的六種方法及對比詳解
引言:為什么列表去重如此重要?
在數(shù)據(jù)處理、日志分析、爬蟲去重等場景中,列表去重幾乎是每個(gè)開發(fā)者都會(huì)遇到的挑戰(zhàn)。但面對不同的數(shù)據(jù)類型(可哈希/不可哈希)和需求(保留順序/高效執(zhí)行),如何選擇最優(yōu)方案?
本文將系統(tǒng)解析6種Python列表去重方法,涵蓋基礎(chǔ)實(shí)現(xiàn)與進(jìn)階技巧,并通過性能測試與實(shí)戰(zhàn)案例,助你徹底掌握這一核心技能!
基礎(chǔ)篇:可哈希元素的去重方法
1. 集合去重法(Set)
原理:利用集合自動(dòng)去重的特性。
優(yōu)點(diǎn):時(shí)間復(fù)雜度 O(n),效率最高。
缺點(diǎn):破壞原始順序,僅適用于可哈希元素(如整數(shù)、字符串)。
li = [11, 22, 44, 33, 33, 22, 22, 11] res = list(set(li)) print(res) # 輸出可能為 [33, 11, 44, 22](順序隨機(jī))
適用場景:快速去重且無需保留順序,如臨時(shí)數(shù)據(jù)清洗。
2. 字典去重法(Python 3.7+)
原理:利用字典鍵的唯一性,且Python 3.7+后字典有序。
優(yōu)點(diǎn):時(shí)間復(fù)雜度 O(n),兼顧效率與順序。
li = [11, 22, 44, 33, 33, 22, 22, 11] unique_list = list(dict.fromkeys(li)) print(unique_list) # 輸出 [11, 22, 44, 33]
3. 新建列表法
原理:逐個(gè)添加不重復(fù)元素至新列表。
優(yōu)點(diǎn):保留順序,邏輯簡單。
缺點(diǎn):時(shí)間復(fù)雜度 O(n²),不適用于大數(shù)據(jù)量。
li = [11, 22, 44, 33, 33, 22, 22, 11]
unique_list = []
for i in li:
if i not in unique_list: # 每次檢查需遍歷新列表
unique_list.append(i)
print(unique_list) # 輸出 [11, 22, 44, 33]適用場景:小規(guī)模數(shù)據(jù)且需簡單實(shí)現(xiàn)的場景。
4. 遍歷刪除法
原理:遍歷原列表副本,刪除重復(fù)項(xiàng)。
優(yōu)點(diǎn):保留順序。
缺點(diǎn):時(shí)間復(fù)雜度 O(n²),性能較差。
li = [11, 22, 44, 33, 33, 22, 22, 11]
unique_list = li.copy()
for i in li.copy():
while unique_list.count(i) > 1: # 頻繁遍歷和刪除
unique_list.remove(i)
print(unique_list) # 輸出 [11, 22, 44, 33]注意事項(xiàng):避免在遍歷時(shí)直接修改原列表,否則可能引發(fā)IndexError。
進(jìn)階篇:不可哈希元素的去重方法
5. JSON序列化去重(字典/嵌套列表)
原理:將字典序列化為字符串,利用集合去重。
適用場景:需完整內(nèi)容去重的不可哈希元素(如字典)。
import json
def deduplicate_dicts_by_content(dict_list):
seen = set()
unique_dicts = []
for d in dict_list:
dict_str = json.dumps(d, sort_keys=True) # 保證鍵順序一致
if dict_str not in seen:
seen.add(dict_str)
unique_dicts.append(d)
return unique_dicts
# 測試用例:去重內(nèi)容相同的字典
li_dicts = [{"a": 1}, {"a": 1}, {"b": 2}, {"a": 1, "b": 2}, {"b": 2, "a": 1}]
print(deduplicate_dicts_by_content(li_dicts)) # 輸出前兩個(gè)重復(fù)項(xiàng)被去重關(guān)鍵點(diǎn):sort_keys=True確保鍵順序一致,避免因順序不同導(dǎo)致誤判。
6. 特定鍵值去重(如根據(jù)ID去重)
原理:根據(jù)字典的某個(gè)鍵(如ID)的值進(jìn)行去重。
適用場景:業(yè)務(wù)中存在唯一標(biāo)識(shí)符(如用戶ID、訂單號(hào))。
def deduplicate_dicts_by_key(dict_list, key):
seen = set()
unique_dicts = []
for d in dict_list:
if key not in d:
unique_dicts.append(d) # 不包含鍵則保留(按需調(diào)整)
continue
if d[key] not in seen:
seen.add(d[key])
unique_dicts.append(d)
return unique_dicts
# 測試用例:根據(jù)鍵"a"去重
li_dicts = [{"a": 1}, {"a": 1}, {"b": 2}, {"a": 3}]
print(deduplicate_dicts_by_key(li_dicts, "a")) # 保留第一個(gè){"a":1}和{"a":3}擴(kuò)展應(yīng)用:支持多鍵組合去重,如key=("user_id", "timestamp")。
性能對比與選型指南
通過實(shí)際測試對比各方法的執(zhí)行效率(以10萬條數(shù)據(jù)為例):
| 方法 | 時(shí)間復(fù)雜度 | 保留順序 | 適用場景 | 10萬數(shù)據(jù)耗時(shí) |
|---|---|---|---|---|
| 集合去重 | O(n) | ? | 快速去重,無需順序 | 0.002秒 |
| 字典去重(Python3.7+) | O(n) | ? | 高效且需順序 | 0.003秒 |
| JSON序列化 | O(n) | ? | 不可哈希元素(如字典) | 0.5秒 |
| 新建列表法 | O(n²) | ? | 小數(shù)據(jù)量 | 12.8秒 |
| 遍歷刪除法 | O(n²) | ? | 極少量數(shù)據(jù) | 15.4秒 |
選型建議:
- 大數(shù)據(jù)量+可哈希元素:優(yōu)先選擇字典去重法(Python 3.7+)。
- 不可哈希元素:使用JSON序列化或特定鍵去重。
- 臨時(shí)快速去重:集合去重法。
- 小數(shù)據(jù)量+保留順序:新建列表法。
實(shí)戰(zhàn)場景解析
場景1:電商訂單去重
假設(shè)有一批訂單數(shù)據(jù),需根據(jù)order_id去重:
orders = [
{"order_id": "A1001", "product": "Phone"},
{"order_id": "A1001", "product": "Laptop"}, # 重復(fù)訂單
{"order_id": "A1002", "product": "Tablet"}
]
unique_orders = deduplicate_dicts_by_key(orders, "order_id")
print(unique_orders) # 保留第一個(gè)A1001和A1002場景2:日志分析去重
處理服務(wù)器日志時(shí),需根據(jù)IP和時(shí)間戳去重:
def deduplicate_logs(logs):
seen = set()
unique_logs = []
for log in logs:
identifier = (log["ip"], log["timestamp"]) # 組合鍵
if identifier not in seen:
seen.add(identifier)
unique_logs.append(log)
return unique_logs總結(jié)與擴(kuò)展
核心總結(jié):
- 可哈希元素優(yōu)先選擇集合或字典去重。
- 不可哈希元素需依賴序列化或業(yè)務(wù)鍵去重。
- 避免在大數(shù)據(jù)中使用時(shí)間復(fù)雜度為O(n²)的方法。
擴(kuò)展思考:
- 如何實(shí)現(xiàn)多條件去重(如同時(shí)根據(jù)用戶ID和時(shí)間范圍)?
- 分布式環(huán)境下如何高效去重(如使用Redis集合)?
以上就是Python列表去重的六種方法及對比詳解的詳細(xì)內(nèi)容,更多關(guān)于Python列表去重的資料請關(guān)注腳本之家其它相關(guān)文章!
相關(guān)文章
Python使用Oracle向量數(shù)據(jù)庫實(shí)現(xiàn)文本檢索系統(tǒng)
在本文中,我們將深入分析一個(gè)使用Oracle向量數(shù)據(jù)庫實(shí)現(xiàn)文本檢索系統(tǒng)的Python代碼,并基于相同的技術(shù)生成一個(gè)新的示例,這個(gè)系統(tǒng)允許我們存儲(chǔ)文檔及其嵌入向量,并執(zhí)行相似性搜索,感興趣的朋友可以參考下2024-07-07
python實(shí)現(xiàn)讀取excel表格詳解方法
python操作excel主要用到xlrd和xlwt兩個(gè)庫,xlrd讀取表格數(shù)據(jù),支持xlsx和xls格式的excel表格;xlwt寫入excel表格數(shù)據(jù)2022-07-07
Python使用VSCode+Anaconda+DeepSeek開發(fā)軟件并打包為exe
本文為Python新手提供從代碼生成到打包exe的完整實(shí)操指南,基于VSCode+Anaconda環(huán)境,詳細(xì)講解:1)工具安裝配置(VSCode、Anaconda、DeepSeek);2)通過DeepSeek生成圖片處理代碼并調(diào)試;3)使用PyInstaller打包為獨(dú)立exe文件,重點(diǎn)解決路徑命名、虛擬環(huán)境管理、常見報(bào)錯(cuò)等問題2026-02-02
Python數(shù)據(jù)可視化之從繪制精美雷達(dá)圖的新手指南
這篇文章主要為大家詳細(xì)介紹了Pytho如何繪制精美雷達(dá)圖從而實(shí)現(xiàn)數(shù)據(jù)可視化的相關(guān)知識(shí),文中的示例代碼講解詳細(xì),感興趣的小伙伴可以了解下2025-11-11
Python循環(huán)結(jié)構(gòu)的應(yīng)用場景詳解
這篇文章主要介紹了Python循環(huán)結(jié)構(gòu)的應(yīng)用場景詳解,文中通過示例代碼介紹的非常詳細(xì),對大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友可以參考下2019-07-07
Django環(huán)境初始化腳本django_setup作用解析
本文主要介紹了Django環(huán)境初始化腳本django_setup作用,文中通過示例代碼介紹的非常詳細(xì),對大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面隨著小編來一起學(xué)習(xí)學(xué)習(xí)吧2026-03-03
在jupyter notebook中調(diào)用.ipynb文件方式
這篇文章主要介紹了在jupyter notebook中調(diào)用.ipynb文件方式,具有很好的參考價(jià)值,希望對大家有所幫助。一起跟隨小編過來看看吧2020-04-04
Pandas:pd.reset_index(drop=False)的使用及說明
`pd.reset_index()`用于重置DataFrame的索引,默認(rèn)情況下(`drop=False`),不會(huì)刪除舊索引,而是將其作為新列添加,若設(shè)置`drop=True`,則會(huì)刪除舊索引2014-12-12
將python文件打包exe獨(dú)立運(yùn)行程序方法詳解
這篇文章主要介紹了將python文件打包exe獨(dú)立運(yùn)行程序方法詳解,需要的朋友可以參考下2020-02-02

