Sarah
Sarah

Reputation: 99

finding common elements between two lists?

I have two lists that are formatted as so:

sortedAlt=[['TIF35', 'TIF35'], ['PTP1', 'SSM4'], ['AMD1', 'PRP40'], ['END3', 'RAD26']]
sortedB=[['SDP1', 'SLT2'], ['ATG34', 'GCD7'], ['END3', 'RAD26'], ['TIF35', 'TIF35']]

and I need to find the shared elements between the two lists. I have tried a couple things:

These two return only []:

sharedEdges = []
temp = [sharedEdges.add((a, b)) for (a, b) in sortedB  
              if (a, b) in sortedAlt]

for (a,b) in sortedAlt:
    print((a,b))
    if (a,b) in sortedB:
        sharedEdges.add((a,b))
print(sharedEdges)

For the above code, I'm pretty sure the issue is within the if statement; if I used the same list input for both, I still get an empty output.

If I try to use the intersection function, I get the error: TypeError: unhashable type: 'list'

sharedEdges = set(sortedAlt) & set(sortedB)
sharedEdges = list(set(sortedAlt)-set(sortedAlt))
print(sharedEdges)

Upvotes: 1

Views: 828

Answers (4)

sahasrara62
sahasrara62

Reputation: 11238

considering inner array element can be non sorted way, sorting them according to the character order then comparing

A=[['TIF35', 'TIF35'], ['PTP1', 'SSM4'], ['AMD1', 'PRP40'], ['END3', 'RAD26']]
B=[['SDP1', 'SLT2'], ['ATG34', 'GCD7'], ['END3', 'RAD26'], ['TIF35', 'TIF35']]

tmp_b = [sorted(inner_list) for inner_list in B]
res = []
for inner_list in A:
    if sorted(inner_list) in tmp_b:
        res.append(inner_list)

print(res)
#OUTPUT  [['TIF35', 'TIF35'], ['END3', 'RAD26']]

considering the inner list order of element not matter then using set operation as suggested by @patrickartner , this will make time complexit small

res = list(set(tuple(i) for i in A).intersection(set(tuple(i) for i in B)))

Upvotes: 1

Alexandre Huat
Alexandre Huat

Reputation: 903

The simpler way is with sets indeed but set accepts hashable objects only. Lists are not hashable but tuples are. So the simpler is simply to cast lists to tuples before constructing sets.

shared_edges = set(map(tuple, sorted_alt)) & set(map(tuple, sorted_b))
shared_edges = list(map(list, shared_edges))  # then go back to lists if you want

By the way, please use the snake case (shared_edges) rather than the mixed case (sharedEdges). This is Python coding convention, see PEP8.

Upvotes: 0

Patrick Artner
Patrick Artner

Reputation: 51683

Convert the inner lists to tuples, so they are hashable. Then you can use

sortedAlt=[['TIF35', 'TIF35'], ['PTP1', 'SSM4'], ['AMD1', 'PRP40'], ['END3', 'RAD26']]
sortedB=[['SDP1', 'SLT2'], ['ATG34', 'GCD7'], ['END3', 'RAD26'], ['TIF35', 'TIF35']]

sharedEdges = set(tuple(i) for i in sortedAlt).intersection( (tuple(i) for i in sortedB))
print(sharedEdges)

Output:

{('END3', 'RAD26'), ('TIF35', 'TIF35')}

This is faster for bigger lists then using a list comprehension with in and probably on par with OlvinRoghts commented map - solution:

# slightly modified from OlvinRoght comment on the question:
s = list(map(list, set(map(tuple, sortedAlt)).intersection(map(tuple, sortedB))))
# [['TIF35', 'TIF35'], ['END3', 'RAD26']]

Upvotes: 1

balderman
balderman

Reputation: 23825

below (convert the list to tuple and use set)

sortedAlt=[['TIF35', 'TIF35'], ['PTP1', 'SSM4'], ['AMD1', 'PRP40'], ['END3', 'RAD26']]
sortedB=[['SDP1', 'SLT2'], ['ATG34', 'GCD7'], ['END3', 'RAD26'], ['TIF35', 'TIF35']]

sortedAltTuple = set(tuple(x) for x in sortedAlt)
sortedBTuple = set(tuple(x) for x in sortedB)
intersections = sortedAltTuple.intersection(sortedBTuple)
print(intersections)

output

{('END3', 'RAD26'), ('TIF35', 'TIF35')}

Upvotes: 0

Related Questions