我写了一个函数来删除"重复"从列表清单。
我的清单的元素是:
[ip, 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多分钟。
答案 0 :(得分:4)
您的方法对列表中的每个元素进行全面扫描,使其占用O(N ** 2)(二次)时间。 list.pop(index)
也很昂贵,因为index
之后的所有内容都会向上移动,使您的解决方案接近O(N ** 3)立方时间。
使用一个集合并添加(email, phonenumber)
元组来检查您是否已经看过该对;对集合进行测试包含需要O(1)恒定时间,因此您可以在O(N)总时间内清除dupes:
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
这会生成 new 列表,旧列表保持不变。
答案 1 :(得分:0)
另一种解决方案可能是使用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))]
答案 2 :(得分:0)
另一种方法可能是使用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
plugin.tx_powermail.settings.setup.prefill.pid = TEXT
plugin.tx_powermail.settings.setup.prefill.pid.stdWrap.data = TSFE:id