简体   繁体   中英

Python comparison in a list of lists of tuples

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)]]

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)]

Solution without assuming sorted input

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)]

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)]

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM