在嵌套列表中查找多个重复项,然后删除它们,同时保留最新条目



我的任务是查看一些注册数据并删除重复的条目。每个条目都包含在一个列表中,所有条目都位于一个列表内。如果的名字、姓氏和电子邮件相同,我想删除条目。数据的简化版本如下所示。

data = [[0,1,'john','doe',test@email],[0,1,'james','doe',eggs@email],[0,1,'john','doe',test@email],[2,11,'john','Stephenson',stack@email]] 

期望的结果将输出相同的列表,然而,重复的第一个条目将被删除,同时保留第二个条目。如下:

data = [0,1,'james','doe',eggs@email],[0,1,'john','doe',test@email],[2,11,'john','Stephenson',stack@email]] 

上面的数据有重复的名字,但当然,人们可以共享名字或姓氏。然而,如果某人的名字、姓氏和电子邮件都相同,那显然是重复的。

无论如何,我该怎么做呢?我正在处理的数据集有1000多个条目。如果我将每个列表与每个列表进行比较,是否需要进行1000^1000次测试?

测试数据:

data = [
[0, 1, "john", "doe", "test@email"],
[0, 1, "james", "doe", "eggs@email"],
[0, 2, "john", "doe", "test@email"],
[2, 11, "john", "Stephenson", "stack@email"],
]
data = data * 2_500

Pandas有一个非常好的drop_duplicates方法,速度非常快。在这种情况下,我只测试最后三列(姓名和电子邮件(,并保留所有重复项中的最后一项。

import pandas as pd
pd.DataFrame(data).drop_duplicates(subset=[2,3,4], keep="last").values.tolist()

输出:

CPU times: user 9.45 ms, sys: 1.64 ms, total: 11.1 ms
Wall time: 9.51 ms
[[0, 1, 'james', 'doe', 'eggs@email'],
[0, 2, 'john', 'doe', 'test@email'],
[2, 11, 'john', 'Stephenson', 'stack@email']
data = [[0,1,'john','doe','test@email'],[0,1,'james','doe','eggs@email'],[0,1,'john','doe','test@email'],[2,11,'john','Stephenson','stack@email']]
final_list = [[*v, *k] for k, v in dict((tuple(i[2:]), i[0:2]) for i in data).items()]
print(final_list)
#[[0, 1, 'john', 'doe', 'test@email'], [0, 1, 'james', 'doe', 'eggs@email'], [2, 11, 'john', 'Stephenson', 'stack@email']]

这里有一个更详细的答案,很容易理解/阅读(至少在我看来(

data = [[0,1,'john','doe',"test@email"],[0,1,'james','doe',"eggs@email"],[0,1,'john','doe',"test@email"],[2,11,'john','Stephenson',"stack@email"]] 

def filter_lst(data):
found = set()
filtered_data = []
for lst in data:
lst_str = str(lst)
if not lst_str in found:
filtered_data.append(lst)
found.add(lst_str)
return filtered_data

您可以存储已在字典中看到的项,然后第二次迭代该字典,并获取每个已看到项的最后一个索引。

from collections import defaultdict
data = [[0,1,'john','doe','test@email'],[0,1,'james','doe','eggs@email'],[0,2,'john','doe','test@email'],[2,11,'john','Stephenson','stack@email']]
def no_dupes(data):
tmp = defaultdict(list)
for idx, d in enumerate(data):
tmp[(d[2], d[3], d[4])].append(idx)
final = []
for v in tmp.values():
idx = v[-1]
final.append(data[idx])
return final
print(no_dupes(data))
[[0, 2, 'john', 'doe', 'test@email'],
[0, 1, 'james', 'doe', 'eggs@email'],
[2, 11, 'john', 'Stephenson', 'stack@email']]

最新更新