0

I have two lists, and I want to remove the elements on a list l1 that have any different substring not mentioned in l2. My lists are the following:

l1 = ['PC||macOS||Xbox One||PlayStation 4||Nintendo Switch',
 'macOS||PC||Xbox One',
 'iOS',
 'PC||PlayStation 4',
 'PC',
 'Web',
 'PC||macOS',
 'PC||macOS||Linux',
 'PC||Linux',
 'PC||Web',
 'PC||Xbox One||PlayStation 4||Nintendo Switch',
 'PC||macOS||Linux||Web',
 'macOS||PC||Linux||PlayStation 4||Xbox One',
 'PC||Android',
 'PC||macOS||Linux||Android',
 'macOS||iOS||Linux||PC||PlayStation 4',
 'Linux',
 'PC||macOS||Web',
 nan,
 'Xbox One||PC||Nintendo Switch||PlayStation 4',
 'iOS||PC||macOS||Linux',
 'PC||macOS||Android||Web',
 'iOS||Linux||PC||macOS',
 'Android',
 'macOS||PC||Linux',
 'Linux||PC'
]

l2 = ['PC', 'macOS', 'Linux', 'mac', 'Web']

What I want to obtain is all combinations in l1 that ONLY have the substrings stated in l2. Therefore, in the new list I won't have any element with words like "Playstation 4" or "iOS" or "Xbox One". Something like:

l3 = [
 'PC',
 'Web',
 'PC||macOS',
 'PC||macOS||Linux',
 'PC||Linux',
 'PC||Web',
 'PC||macOS||Linux||Web',
 'PC||macOS||Linux||Android',
 'Linux',
 'PC||macOS||Web',
 'macOS||PC||Linux',
 'Linux||PC'
]
quamrana
  • 37,849
  • 12
  • 53
  • 71
marsolmos
  • 748
  • 9
  • 24
  • what have you done so far? also may I ask if you are familiar with regular expressions? cause I think it will do the job :D – Ice Bear Dec 16 '20 at 15:36
  • I've tried with nested for loops and 'str.contains()' and adapting this https://stackoverflow.com/questions/4211209/remove-all-the-elements-that-occur-in-one-list-from-another but with no result – marsolmos Dec 16 '20 at 15:40
  • Loop over the items in list1. For each item, split it on `||` and do a nested loop on the split items, comparing each one to the items in list2. If you get to the end of the nested loop without finding any matches, append the item to list3. – John Gordon Dec 16 '20 at 15:45

2 Answers2

3

Make l2 a set for fast lookup then use all with a generator comprehension:

l2_set = set(l2)
l3 = [x for x in l1 if all(chunk in l2_set for chunk in x.split("||"))]
Aplet123
  • 33,825
  • 1
  • 29
  • 55
3

using sets is pretty easy.

l3 = [v for v in l1 if set(v.split('||')) <= set(l2)]

gonna have to filter out that errant nan though...

acushner
  • 9,595
  • 1
  • 34
  • 34