Reputation: 73
I´m working on python and I basically have a lists with different elements. If I print some of the elements it looks like the following:
print('%s'%list[0])
print('%s'%list[1])
Output:
[('A', 'B'), ('D', 'E'), ('B', 'Z'), ('Z', 'D')]
[('B', 'M'), ('M', 'R'), ('B', 'A'), ('R', 'Z'), ('H', 'M')]
I want to check if one of the elements is repeated in both lists. But it can be repeated in a different order. For example, the element ('A', 'B') IS repeated but with a different order ('B', 'A') in the second list.
I want to compare list[0][0] (that is ('A', 'B')) with all of the elements of list[1] and obtain true for element list[0][2].
How could I do this??
Thanks
Upvotes: 1
Views: 106
Reputation: 2367
You can use the set.intersection
method to return any shared elements from two (or more) sets. In the example below, each list of tuples is first converted to a set of sets. Note that each tuple is mapped to a frozenset
so it remains hashable. The function then returns a list of any shared items. Just to remain consistent with the original input object type, each item in the return list is converted back into a tuple.
def listSharedItems( list1, list2 ):
list1_sets = set(map(frozenset,list1))
list2_sets = set(map(frozenset,list2))
intersect = list1_sets.intersection(list2_sets)
return map(tuple,intersect)
>>> # Example usage:
>>> alist = [[('A','B'), ('D','E'), ('B','Z'), ('Z','D')],
[('B','M'), ('M','R'), ('B','A'), ('R','Z'), ('H','M')]]
>>> listSharedItems( alist[0], alist[1] )
>>> [('A', 'B')]
Upvotes: 0
Reputation: 4394
You can use two for-loops to obtain true if the elements match, by converting them to sets (because sets don't have an order):
l1 = [('A', 'B'), ('D', 'E'), ('B', 'Z'), ('Z', 'D')]
l2 = [('B', 'M'), ('M', 'R'), ('B', 'A'), ('R', 'Z'), ('H', 'M')]
elementToCompare = set(l1[0])
for i in l2:
if elementToCompare == set(i):
print("%s is the same as %s"%(l1[0], i))
Output:
('A', 'B') is the same as ('B', 'A')
Upvotes: 0
Reputation: 46921
you can turn your tuples into sets; that way the order will not matter:
a = [('A', 'B'), ('D', 'E'), ('B', 'Z'), ('Z', 'D')]
b = [('B', 'M'), ('M', 'R'), ('B', 'A'), ('R', 'Z'), ('H', 'M')]
a_set = list(set(item) for item in a)
b_set = list(set(item) for item in b)
# create a list of items that are in a and b:
res = [item for item in a_set if item in b_set]
print(res) # [{'A', 'B'}]
if speed is an issue you could even to this:
a_set = set(frozenset(item) for item in a)
b_set = set(frozenset(item) for item in b)
res = a_set & b_set
# {frozenset({'A', 'B'})}
this could then easily be converted back to a list containing tuples with res = [tuple(item) for item in res]
.
note that duplicates will be treated as single entries in the last version.
Upvotes: 2
Reputation: 82949
In case the elements can contain some items multiple times, and set
does thus not work, you could also use sorted
to normalize the order within the elements.
>>> a = [('A', 'B'), ('D', 'E'), ('B', 'Z'), ('Z', 'D')]
>>> b = [('B', 'M'), ('M', 'R'), ('B', 'A'), ('R', 'Z'), ('H', 'M')]
>>> b_set = set([tuple(sorted(x)) for x in b])
>>> [x for x in [tuple(sorted(y)) for y in a] if x in b_set]
[('A', 'B')]
Note that if you want to use a set
to make the lookup faster, you have to wrap the sorted
elements into tuples
so they are hashable.
Upvotes: 1