Roman
Roman

Reputation: 3241

Test if all elements are in another list in Python

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

Answers (4)

Joe T. Boka
Joe T. Boka

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

imbellish
imbellish

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

Makoto
Makoto

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

turbulencetoo
turbulencetoo

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

Related Questions