[英]Remove duplicates from a list of list based on a subset of each list
我編寫了一個函數來從列表列表中刪除“重復項”。
我的清單的元素是:
[ip, email, phone number].
我想刪除具有相同 EMAIL 和 PHONE NUMBER 的子列表,我並不真正關心 IP 地址。
我目前使用的解決方案是:
def remove_duplicate_email_phone(data):
for i in range(len(data)):
for j in reversed(range(i+1,len(data))):
if data[i][1] == data[j][1] and data[i][2] == data[j][2] :
data.pop(j)
return data
我想優化這個。 花了30多分鍾才得到結果。
您的方法對列表中的每個元素進行全面掃描,使其花費 O(N**2)(二次)時間。 list.pop(index)
也很昂貴,因為index
后面的所有內容都向上移動,使您的解決方案接近 O(N**3) 立方時間。
使用一個集合並在其中添加(email, phonenumber)
元組以檢查您是否已經看過該對; 測試對集合的遏制需要 O(1) 恆定時間,因此您可以在 O(N) 總時間內清除欺騙:
def remove_duplicate_email_phone(data):
seen = set()
cleaned = []
for ip, email, phone in data:
if (email, phone) in seen:
continue
cleaned.append([ip, email, phone])
seen.add((email, phone))
return cleaned
這會生成一個新列表,舊列表保持不變。
另一種解決方案可能是使用 groupby。
from itertools import groupby
from operator import itemgetter
deduped = []
data.sort(key=itemgetter(1,2))
for k, v in groupby(data, key=itemgetter(1,2):
deduped.append(list(v)[0])
或使用列表理解:
deduped = [next(v) for k, v in groupby(data, key=itemgetter(1,2))]
另一種方法可能是使用Counter
from collections import Counter
data = [(1, "a@b.com", 1234), (1, "a@b.com", 1234), (2, "a@b.com", 1234)]
counts = Counter([i[:2] for i in data])
print [i for i in data if counts[i[:2]] == 1] # Get unique
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.