在 Python 中,“按值批量刪除” 並 “去重” 的核心是 先篩選出不需要刪除的元素,再通過集合(set)自動去重。以下是 4 種常用實現方式,覆蓋不同場景(是否保留原順序、是否修改原列表、效率要求),附帶代碼示例和詳細解析:
一、核心需求拆解
- 按值批量刪除:給定要刪除的多個值(如
[2,3,5]),從列表中移除所有匹配的元素; - 去重:最終結果列表中不包含重複元素(即使原列表有重複的保留元素);
- 可選需求:是否保留原列表的元素順序、是否允許修改原列表、是否需要高效處理大數據量。
二、4 種實現方式(按推薦優先級排序)
方式 1:列表推導式 + set(推薦,保留順序 + 高效)
核心邏輯
用列表推導式篩選出 “不在刪除值列表” 中的元素,再通過 dict.fromkeys() 或 OrderedDict 去重並保留原順序(Python 3.7+ 後 dict 有序)。
代碼示例
python
運行
# 原列表
nums = [1, 2, 3, 2, 4, 5, 5, 6, 3, 7, 7]
# 要刪除的值
del_values = {2, 3, 5} # 用 set 存儲,查找效率 O(1)(推薦)
# 步驟 1:篩選出不刪除的元素(保留原順序)
filtered = [x for x in nums if x not in del_values]
# 步驟 2:去重並保留原順序(Python 3.7+)
result = list(dict.fromkeys(filtered)) # dict.fromkeys() 自動去重,保留插入順序
print(result) # 輸出:[1, 4, 6, 7](保留原順序,無重複)
原理
- 列表推導式
[x for x in nums if x not in del_values]:遍歷原列表,僅保留不在del_values中的元素(保留原順序),時間複雜度 O (n); dict.fromkeys(filtered):用篩選後的列表作為字典的鍵,字典的鍵自動去重,且 Python 3.7+ 後保留鍵的插入順序(即原列表順序),時間複雜度 O (m)(m 為篩選後列表長度);- 整體時間複雜度 O (n + m) = O (n)(高效)。
優點
- 保留原元素順序(符合日常需求);
- 效率高(篩選和去重都是線性時間);
- 語法簡潔,一行可完成(合併步驟):
python
運行
result = list(dict.fromkeys([x for x in nums if x not in del_values]))
適用場景
- 日常開發中 “按值批量刪 + 去重 + 保留順序” 的核心場景(90% 以上場景適用)。
方式 2:set 差集(最快,不保留順序)
核心邏輯
將原列表和刪除值列表都轉為 set,通過集合差集直接獲取 “保留的元素”,再轉回列表(set 自動去重,但無序)。
代碼示例
python
運行
nums = [1, 2, 3, 2, 4, 5, 5, 6, 3]
del_values = {2, 3, 5}
# 步驟 1:轉為 set,求差集(自動去重+刪除指定值)
result_set = set(nums) - del_values # 差集:nums 中不在 del_values 的元素
# 步驟 2:轉回列表(無序)
result = list(result_set)
print(result) # 輸出:[1, 4, 6](順序不固定,自動去重)
原理
set(nums):原列表轉集合,自動去重(時間複雜度 O (n));set(nums) - del_values:集合差集運算,獲取保留的元素(時間複雜度 O (min (n, k)),k 為刪除值個數);- 整體時間複雜度 O (n),是所有方式中最快的。
優點
- 速度極快(集合運算底層優化);
- 代碼極簡(一行可完成):
python
運行
result = list(set(nums) - {2, 3, 5})
缺點
- 不保留原列表的元素順序(
set是無序結構); - 自動去重(若需保留重複元素,不適用)。
適用場景
- 無需保留原順序,僅需 “快速刪除指定值 + 去重” 的場景(如數據清洗、標籤過濾)。
方式 3:倒序遍歷 + pop ()(修改原列表,保留順序)
核心邏輯
倒序遍歷原列表,若元素在刪除值列表中,用 pop() 刪除(倒序避免索引錯亂),同時用 set 記錄已保留的元素,實現去重。
代碼示例
python
運行
nums = [1, 2, 3, 2, 4, 5, 5, 6, 3, 7, 7]
del_values = {2, 3, 5}
seen = set() # 記錄已保留的元素,用於去重
# 倒序遍歷(索引從 len(nums)-1 到 0)
for i in range(len(nums)-1, -1, -1):
current = nums[i]
# 條件:1. 元素不在刪除值列表;2. 元素未被保留過(去重)
if current in del_values or current in seen:
nums.pop(i) # 刪除元素(倒序不影響索引)
else:
seen.add(current) # 記錄已保留的元素
print(nums) # 輸出:[1, 4, 6, 7](保留原順序,修改原列表)
原理
- 倒序遍歷:避免正序刪除導致的索引偏移(刪除後面的元素不影響前面的索引);
seen集合:記錄已保留的元素,再次出現時直接刪除(實現去重);pop(i):刪除當前索引元素,時間複雜度 O (n)(非末尾元素需移動後續元素),但因倒序,移動次數較少。
優點
- 直接修改原列表(無額外內存佔用,適合大數據量);
- 保留原元素順序。
缺點
- 時間複雜度 O (n²)(最壞情況,如刪除大量元素時多次
pop移動); - 代碼較繁瑣(需維護
seen集合和倒序遍歷)。
適用場景
- 需修改原列表,且內存敏感(如超大列表,無法生成新列表)的場景。
方式 4:pandas 庫(大數據量 + 高效,保留順序)
核心邏輯
利用 pandas 庫的 Series 數據結構,通過 isin() 篩選元素,drop_duplicates() 去重,適合處理十萬級以上的大數據量。
代碼示例
python
運行
import pandas as pd
nums = [1, 2, 3, 2, 4, 5, 5, 6, 3, 7, 7] * 1000 # 放大為 11000 個元素(模擬大數據)
del_values = {2, 3, 5}
# 步驟 1:轉為 pandas Series
s = pd.Series(nums)
# 步驟 2:篩選出不在刪除值列表的元素
filtered = s[~s.isin(del_values)] # ~ 表示取反
# 步驟 3:去重並保留原順序
result = filtered.drop_duplicates().tolist()
print(result) # 輸出:[1, 4, 6, 7](保留原順序,高效處理大數據)
原理
s.isin(del_values):判斷每個元素是否在刪除值列表中,返回布爾 Series(時間複雜度 O (n));s[~s.isin(del_values)]:篩選出不刪除的元素(保留原順序);drop_duplicates():去重並保留首次出現的元素(時間複雜度 O (n));pandas底層用 C 語言優化,大數據量下效率遠高於純 Python 方法。
優點
- 大數據量處理極快(十萬級以上元素優勢明顯);
- 保留原順序,語法簡潔。
缺點
- 需安裝
pandas庫(非 Python 內置); - 小數據量下(如幾百個元素),因庫調用開銷,效率不如方式 1 和 2。
適用場景
- 數據分析、大數據處理場景(如處理 CSV 數據、日誌數據中的批量刪除 + 去重)。
三、不同場景的最優選擇
|
場景描述
|
推薦方式
|
核心優勢
|
|
日常場景(保留順序 + 高效 + 簡潔)
|
方式 1(列表推導式 + set)
|
兼顧順序、效率和簡潔性,適用面廣
|
|
無需保留順序(追求最快速度)
|
方式 2(set 差集)
|
速度極快,代碼極簡
|
|
內存敏感(超大列表,修改原列表)
|
方式 3(倒序遍歷 + pop)
|
無額外內存佔用
|
|
大數據量(十萬級以上,保留順序)
|
方式 4(pandas)
|
底層優化,效率遠超純 Python
|
四、避坑重點
- 刪除值用 set 存儲:無論哪種方式,
del_values建議用set(如{2,3,5}),而非列表([2,3,5])——in操作在 set 中是 O (1),列表中是 O (k)(k 為刪除值個數),大數據量下差異明顯; - 避免正序遍歷刪除:如
for num in nums: if num in del_values: nums.remove(num),會導致索引偏移,元素漏刪,且無法實現去重; - 去重並保留順序的關鍵:Python 3.7+ 用
dict.fromkeys(),Python 3.6 及以下用collections.OrderedDict.fromkeys()(功能一致); - pandas 適用於大數據:小數據量(如幾千個元素)用方式 1 即可,無需引入 pandas(避免庫依賴和調用開銷)。
五、總結
- 日常開發優先選 方式 1(列表推導式 + set) ,兼顧順序、效率和簡潔性;
- 追求極致速度且無需順序選 方式 2(set 差集) ;
- 內存敏感或必須修改原列表選 方式 3(倒序遍歷 + pop) ;
- 大數據量處理選 方式 4(pandas) 。
根據實際需求(是否保留順序、數據量、內存限制)選擇合適的方式,即可高效實現 “按值批量刪 + 去重”。