0

How to select lists that do NOT include all ordered sequences contained in sl? This is a code:

l = [
 ['s1', 's5', 's6', 's8', 's10', 's5'],
 ['s1', 's5', 's8', 's10', 's5', 's6', 's8', 's15', 's23'],
 ['s1', 's5', 's6', 's10', 's14']
]
sl = [['s5','s6','s8'],['s15', 's23']]


from more_itertools import windowed
from functools import partial

def ordered_check(x, sub):
    s = tuple(sub)
    for y in windowed(x, len(sub)):
        if s == y:
            return True
    return False

def ordered_check_all(x, subs):
    return any(~ordered_check(x, sub) for sub in subs)

def check_factory(subs):
    return partial(ordered_check_all, subs=subs)

list(filter(check_factory(sl), l))

The expected output is this one (because it does not contain all ordered sequences of sl):

['s1', 's5', 's6', 's10', 's14']

However, if I run this code, it returns all sublists of l. Not sure why any(~ordered_check does not work.

UPDATE:

I tried to substitute ~ with not as suggested in the answer. But it does not work for the following example:

l = [['p4', 'p5', 'p7', 'p9', 'p11', 'p13', 'p15', 'p13', 'p15', 'p23', 'p19', 'p21', 'p16', 'p17', 'p18', 'p16', 'p25'], 
     ['p4', 'p5', 'p7', 'p9', 'p11', 'p13', 'p15', 'p13', 'p15', 'p23', 'p19', 'p21', 'p16', 'p25'], 
     ['p4', 'p5', 'p7', 'p9', 'p11', 'p13', 'p15', 'p13', 'p15', 'p23', 'p20', 'p22', 'p20', 'p23', 'p19', 'p21', 'p16', 'p17', 'p18', 'p16', 'p25'],
     ['p4', 'p5', 'p7', 'p9', 'p11', 'p13', 'p15', 'p13', 'p15', 'p23', 'p20', 'p22', 'p20', 'p23', 'p19', 'p21', 'p16', 'p25']
]

sl = 
[
 ['p15', 'p23', 'p15'],
 ['p13', 'p15', 'p13', 'p15', 'p14'],
 ['p14', 'p15', 'p14', 'p15', 'p13'],
 ['p13', 'p15', 'p23', 'p19'],
 ['p13', 'p15', 'p23', 'p20'],
 ['p14', 'p15', 'p23', 'p19'],
 ['p14', 'p15', 'p23', 'p20']
]
Fluxy
  • 2,838
  • 6
  • 34
  • 63

2 Answers2

1

You should replace:

any(~ordered_check

with

any( not ordered_check
lenik
  • 23,228
  • 4
  • 34
  • 43
0

Basically you can check if a list is contained in another list without breaking the order with the next method:

def contains_list(list_1, list_2):
    n = len(list_1) 
    return any(list_1 == list_2[i:i + n] for i in range(len(list_2)-n + 1)) 

Then you can pass the different lists of the sl variable on this method:

result = []
for check_list in sl:
   if not any(contains_list(check_list, source_list) for source_list in l)
       result.append(check_list)

print(result)

Note: Sorry I couldn't try the code (on my mobile now), so maybe it's not 100% working.

I hope it helps.

edgarzamora
  • 1,472
  • 1
  • 9
  • 17