[英]remove duplicates (tuple of tuples)
輸入數據:
input_tuple = (
(1, 'name1', 'Noah'),
(1, 'name2', 'Liam'),
(2, 'name3', 'Mason'),
(3, 'name4', 'Mason'),
(4, 'name5', 'Noah'),
(4, 'name6', 'Liam'),
(5, 'name7', 'Elijah'),
(5, 'name8', 'Noah'),
(5, 'name9', 'Liam')
)
轉換為dict(key,value):
input_tuple = {
1: [['name1', 'Noah'], ['name2', 'Liam']],
2: [['name3', 'Mason']],
3: [['name4', 'Mason']],
4: [['name5', 'Noah'], ['name6', 'Liam']],
5: [['name7', 'Elijah'], ['name8', 'Noah'],
['name9', 'Liam']]
}
為了了解數據模型做了更多的過濾:
dict =
{
1: ['Noah', 'Liam'],
2: ['Mason'],
3: ['Mason'],
4: ['Noah', 'Liam'],
5: ['Elijah', 'Noah', 'Liam']
}
現在,我想消除重復項,然后返回到元組,如下所示:重復匹配條件:1)如果len(value)> 1 2)值應完全匹配而不是部分匹配,則消除重復項。
注意:鍵2和3的值不是重復的,因為len(value)不是-gt 1鍵4的值已經消失了,因為它正好是重復的,因為我們正在進行精確匹配,因此鍵5中的值['Noah',Liam]不會走。
output_tuple =
(
(1, 'name1', 'Noah'),
(1, 'name2', 'Liam'),
(2, 'name3', 'Mason'),
(3, 'name4', 'Mason'),
(5, 'name7', 'Elijah'),
(5, 'name8', 'Noah'),
(5, 'name9', 'Liam')
)
我嘗試過的代碼:
from functools import reduce
from collections import defaultdict
input_tuple_dictionary = defaultdict(list)
for (key, *value) in input_tuple:
input_tuple_dictionary[key].append(value[1])
input_tuple_dictionary
for index in range(len(input_tuple_dictionary)-1):
for key, value in input_tuple_dictionary.items():
if len(value) > 1:
if value == value[index+1]:
print(key)
# Using the dict format of yours
data = [set(dict[x]) for x in range(1, len(dict) + 1)]
input_tuple = dict
seen = []
output_tuple = []
for i in range(len(data)):
if (data[i] not in seen) or len(data[i]) == 1:
for j in range(len(input_data)):
if input_data[j][0] == i + 1:
output_tuple.append(input_data[j])
seen.append(data[i])
output_tuple = tuple(output_tuple)
如果您不明白,請詢問
祝好運
跳過重復項的一種常見解決方案是保留一個包含您已經看到的所有元素的集合。 如果該對象以前見過,則不要將其添加到結果中。
棘手的一點是,您要嘗試刪除的對象是集合中位於不同元組中的多個對象的集合。 使用groupby
是在一個方便的程序包中將這些對象聚集在一起的有效方法。
from itertools import groupby
input_tuple = (
(1, 'name1', 'Noah'),
(1, 'name2', 'Liam'),
(2, 'name3', 'Mason'),
(3, 'name4', 'Mason'),
(4, 'name5', 'Noah'),
(4, 'name6', 'Liam'),
(5, 'name7', 'Elijah'),
(5, 'name8', 'Noah'),
(5, 'name9', 'Liam')
)
seen = set()
result = []
for _, group in groupby(input_tuple, key=lambda t: t[0]):
#convert from iterator to list, since we want to iterate this more than once
group = list(group)
#extract just the names from each tuple.
names = tuple(t[2] for t in group)
#check for duplicates, but only for name groups with more than one element.
if len(names) == 1 or names not in seen:
result.extend(group)
seen.add(names)
print(result)
結果:
[(1, 'name1', 'Noah'), (1, 'name2', 'Liam'), (2, 'name3', 'Mason'), (3, 'name4', 'Mason'), (5, 'name7', 'Elijah'), (5, 'name8', 'Noah'), (5, 'name9', 'Liam')]
from collections import defaultdict
dct = defaultdict(list)
for k,n_id,name in input_tuple:
dct[k].append(name)
#print(dct)
seen = set()
ignore_id_set = set()
for _id, _namelst in dct.items():
if len(_namelst) > 1:
k = tuple(sorted(_namelst)) # note 1
if k not in seen:
seen.add(k)
else:
ignore_id_set.add(_id) # duplicate
#print(seen)
# del dct,seen # dct,seen are now eligible for garbage collection
output = tuple(item for item in input_tuple if item[0] not in ignore_id_set)
print(output)
'''
note 1:
important to sort **if** situations like this can be possible
(1, 'name1', 'Noah'),
(1, 'name2', 'Liam'),
(4, 'name6', 'Liam'),
(4, 'name5', 'Noah'),
because when we will create dct it will result in
1 : [Noah,Liam]
4 : [Liam,Noah]
since we want to treat them as duplicates we need to sort before creating their hash( via tuple)
**else** no need to do sort
'''
下面是一個使用一個溶液defaultdict
的set
對象和toolz.unique
。 toolz.unique
等效於文檔中提供的itertools
unique_everseen
配方 。
這樣做的想法是找到具有單獨值的鍵以及沒有重復值的鍵。 這兩類的結合讓你的結果。
from collections import defaultdict
from toolz import unique
dd = defaultdict(set)
for k, _, v in input_tuple:
dd[k].add(v)
lones = {k for k, v in dd.items() if len(v) == 1}
uniques = set(unique(dd, key=lambda x: frozenset(dd[x])))
res = tuple(i for i in input_tuple if i[0] in lones | uniques)
結果:
print(res)
((1, 'name1', 'Noah'),
(1, 'name2', 'Liam'),
(2, 'name3', 'Mason'),
(3, 'name4', 'Mason'),
(5, 'name7', 'Elijah'),
(5, 'name8', 'Noah'),
(5, 'name9', 'Liam'))
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.