Andi
Andi

Reputation: 4885

How to check which elements of one iterable are also in another?

I have two tuples of possibly different lengths:

t1 = ('abc', 'def', 'ghi', 'jkl')
t2 = ('def', 'jkl')

I need to get a resulting tuple that contains bool, holding True if the value in t1 is in t2 and False otherwise.

I am looking for the following result:

result = (False, True, False, True)

Upvotes: 0

Views: 127

Answers (2)

Altareos
Altareos

Reputation: 882

Using a generator expression and the tuple constructor, you can iterate over t1 and check if each element is in t2:

result = tuple(element in t2 for element in t1)

If t2 is a large tuple, it may be faster to convert it to a set first.

s2 = set(t2)
result = tuple(element in s2 for element in t1)

Upvotes: 7

dawg
dawg

Reputation: 104005

With Python 3.6+, since it maintains insertion order, you can do this using .fromkeys() and .update():

di = dict.fromkeys(t1, False)
di.update(dict.fromkeys(t2, True))
# di = {'abc': False, 'def': True, 'ghi': False, 'jkl': True}
 
>>> tuple(di.values())
(False, True, False, True)

Which can be shortened to:

results=tuple({ **{}.fromkeys(t1, False), **{}.fromkeys(t2, True) }.values())

Or, with Python 3.9+:

result=tuple(({}.fromkeys(t1, False) | {}.fromkeys(t2, True)).values())

If you want to make sure that a value in t2 is not inserted into result as True without a corresponding value in t1, just have a set to determine the overlapping elements:

result=tuple(({}.fromkeys(t1, False) | {}.fromkeys(set(t1)&set(t2), True)).values())

This method is potentially faster for larger sequences since in can be slower for long sequences.

Upvotes: 0

Related Questions