Reputation: 3241
I want to test if reference_list
contains all of the items in required_strings
.
required_strings = ['apple','banana','carrot']
reference_list = [['apple','tree'],
['banana','grass'],
['carrot','grass']]
I want to get true or false as the test result. The expected answer is 'true'.
This is what I had attempted:
test = [i for i in reference_list if any(s in i for s in required_strings)]
print test
Upvotes: 3
Views: 79
Reputation: 6581
Python 2 This is one way to do it:
import itertools
required_strings = ['apple','banana','carrot']
reference_list = [['apple','tree'],
['banana','grass'],
['carrot','grass']]
x = list(itertools.chain(*reference_list))
print all(l in x for l in required_strings )
Output:
True
Upvotes: 0
Reputation: 136
Here's a comprehension that returns a list of bools:
>>> test = [(True if i in s else False) for i in required_strings for s in reference_list]
[True, False, False, False, True, False, False, False, True]
Alternatively, use a generator comprehension to check against the length of the original required strings list. Notice the use of ( ) instead of [ ].
>>> test = ((True if i in s else False) for i in required_strings for s in reference_list)
Then, check it against the length:
>>> counter = 0
>>> for truthiness in test:
... if truthiness == True:
... counter += 1
>>> len(required_strings) == counter
True
Edit: this would probably only work in Python 3.4+ but I thought it would be worth putting forth.
Upvotes: 0
Reputation: 106518
You can do this by making use of set
and itertools.chain
. We're going to take advantage of some set theory and regard required_strings
and reference_list
as sets, and demonstrate that required_strings <= reference_list
; that is, the required strings set is completely contained inside of the reference list.
First, use itertools.chain
to flatten the shallow list.
from itertools import chain
chain(*reference_list) # Iterable object
Next, turn both the chained list and the tested list into sets and compare to see if one set is completely contained in the other.
from itertools import chain
set(required_strings) <= set(chain(*reference_list))
If you're keen on not using chain
, then you can use sum(list_of_lists, [])
to reduce it instead.
set(required_strings) <= set(sum(reference_lists, []))
However, I would strongly encourage that you use set
instead of list
, as this sort of problem is better suited towards a set
. You also don't have to import it; you can just use the class much like you do list
.
Upvotes: 4
Reputation: 3701
No reason to try anything super fancy or concise until you have a working solution you understand.
Try at first to make your answer as similar to the english specification of the problem as you can. Basically you should loop over strings in the required list and check if they are in any of the sub lists. Here's a stub that can be made a function.
for req_string in required_strings:
appears_in_reference = False
for sub_list in reference_list:
if req_string in sub_list:
appears_in_reference = True
break
if not appears_in_reference:
return False
return True
Upvotes: 1