Reputation: 282
I am new on python and I have a question about comparison in list of tuples. I have a list with duplicates of the second element in the tuple and I want to print only the first appearance of this tuple. For example, for this list:
[(1, 2), (5, 10), (6, 10), (24, 35), (30, 35)]
I have this function:
def func(lst):
list_first = []
#Checks if 2 elements have the same second value.
for i in range(len(lst)-1):
if(lst[i][1] == lst[i+1][1]):
first = (lst[i][0]),lst[i][1]
list_first.append(first) #append only the first element
print list_first
My function's output is:
[(5, 10), (24, 35), (30, 35)]
But my expected output is:
[(5, 10), (24, 35)]
How can I fix it?
UPDATE
I have to do all this algorithm on list of lists. So for the input:
[[(0, 3), (1, 3), (2, 3), (3, 3), (4, 3)], [(5, 3), (6, 3), (7, 3), (8, 3), (9, 3)], [(10, 3), (11, 3), (12, 3), (13, 3), (14, 3)]]
I want the output to be:
[[(0, 3)], [(5, 3)], [(10, 3)]]
I'v tried oh change the solutions I'd got here. But all I'v got was:
[[(0, 3)], [(0, 3)], [(0, 3)]]
Upvotes: 3
Views: 846
Reputation: 9257
A solution for your question using groupby
from itertools
module:
Edit: Like what @AKS suggests, here is a function with multiple form of inputs.
from itertools import groupby
def comp_list(a = list()):
final = []
for _, v in groupby(sorted(a, key = lambda x : x[1]) , lambda x : x[1]):
b = list(v)
if len(b) > 1:
final.append(b[0])
return final
a1 = [(1, 2), (5, 10), (6, 10), (24, 35), (30, 35)]
a2 = [(1, 2), (5, 10), (6, 10), (24, 35), (30, 35), (40, 35)]
a3 = [(5, 10), (24, 35), (30, 35), (20, 5), (15, 4), (21, 5), (13, 4)]
a4 = [(1, 2),(6, 10), (5, 10), (24, 35), (30, 35)]
print(comp_list(a1))
print(comp_list(a2))
print(comp_list(a3))
print(comp_list(a4))
Output:
[(5, 10), (24, 35)]
[(5, 10), (24, 35)]
[(15, 4), (20, 5), (24, 35)]
[(6, 10), (24, 35)]
Upvotes: 2
Reputation: 85432
You can use a dictionary that uses the second value in the tuple as key.
If the this key appears the second time, append the already seen tuple to your result. Don't append again if you see the tuple a third or more time.
The set added
contains the already added second tuple entries if there are more than two occurrences found:
from __future__ import print_function # makes work in Python 2 and 3
def find_first(lst):
seen = {}
res = []
added = set()
for elem in lst:
key = elem[1]
if key in seen and key not in added:
res.append(seen[key])
added.add(key)
else:
seen[key] = elem
return res
Testing with a lis. Note the last element (60, 10)
with the 10
repeating a third time:
L = [(1, 2), (5, 10), (6, 10), (24, 35), (30, 35), (60, 10)]
print(find_first(L))
Output:
[(5, 10), (24, 35)]
It does NOT use sorting and works for this example data:
L = [(1, 2), (6, 10), (5, 10), (24, 35), (30, 35), (60, 10)]
print(find_first(L))
Output:
[(6, 10), (24, 35)]
The solution from the other answer does not work for this data:
from itertools import groupby
L = [(1, 2), (6, 10), (5, 10), (24, 35), (30, 35), (60, 10)]
final = []
for _, v in groupby(sorted(a) , lambda x : x[1]):
b = list(v)
if len(b) > 1:
final.append(b[0])
print(final)
Output:
[(5, 10), (24, 35)]
Upvotes: 2
Reputation: 515
Here is a small method that can help you here
def removeDuplicateTuple(sampleList):
uniqueList = []
entryLog = {}
processedEntries = []
for x, y in sampleList:
if entryLog.get(y)==None:
entryLog[y] = (x,y)
else:
if(entryLog.get(y) not in processedEntries):
uniqueList.append(entryLog.get(y))
processedEntries.append(entryLog.get(y))
return uniqueList
test:
[(1, 2), (5, 10), (6, 10), (24, 35), (30, 35), (45, 2)]
output:
[(5, 10), (24, 35), (1, 2)]
Upvotes: 0