Reputation: 99
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
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
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
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
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