Reputation: 99
I have a list of lists, which each consists of three tuples of four-value combinations of the integers 0
to 11
, e.g.:
[(0, 1, 4, 7), (2, 3, 6, 9), (5, 8, 10, 11)]
I want to be able to find if this list (and others) contains certain integers in at least one of the tuples, and contains other integers in at least one of the other tuples.
It's simple enough if I want to check if at least one tuple contains certain integers. For instance, you could have something like:
def func_1(lst):
for tup in lst:
if {0,1}.issubset(tup):
return True
return False
which returns True
for [(0, 1, 4, 7), (2, 3, 6, 9), (5, 8, 10, 11)]
...but False
for [(0, 4, 7, 9), (1, 2, 3, 6), (5, 8, 10, 11)]
But what if I want to find if one tuple contains {0,1}
and another separate tuple contains {2, 3}
? Something like this won't work:
def func_2(lst):
for tup in lst:
if {0,1}.issubset(tup) or {2,3}.issubset(tup):
return True
return False
That would return True
for both of the above lists, when it is only True
for the first one.
Upvotes: 0
Views: 83
Reputation: 4876
Use 2 functions. The first checks for your first match. Then call the second on the remaining elements to check for your second match. If there is none, continue your previous search.
def sub_search(lst):
for tup in lst:
if {2,3}.issubset(tup):
return True
return False
def search(lst):
for i,tup in enumerate(lst):
if {0,1}.issubset(tup):
if sub_search(lst[0:i]+lst[i+1:]):
return True
return False
Upvotes: 0
Reputation: 1125018
You'd have to iterate over the tuples, and test each against both sets. Then if one of the sets matches, remove that set from consideration and only return true if the all sets have matches in the remainder:
def func_2(lst):
sets_to_test = {frozenset({0,1}), frozenset({2,3})}
for tup in lst:
matched = next((s.issubset(tup) for s in sets_to_test), None)
if matched:
s.remove(matched)
if not sets_to_test:
# all sets have matches to separate tuples
return True
return False
This approach will extend to more sets too.
Note that this could miss matches if there are tuples that are subsets of either one of the sets. If this is a possibility you need to account for, I'd use recursion to handle this option:
def func_2(lst, sets_to_test=None):
if sets_to_test is None:
sets_to_test = {frozenset({0,1}), frozenset({2,3})}
if not sets_to_test:
# all sets have matched
return True
if not lst:
# no tuples remain
return False
for i, tup in enumerate(lst):
for set_to_test in sets_to_test:
if set_to_test.issubset(tup):
if func_2(lst[i + 1:], sets_to_test - {set_to_test}):
return True
return False
So whenever one of the sets matches, recursion is used to test the remaining sets and list of tuples; if that recursive call doesn't return True
, further sets are tested.
Upvotes: 1