0
#sub list test 1
a = [1,1,2]
b = [0, 1,1,1,2,1]

#sub list test 2
c = [4,5]
d = [2,3,4,5,6]
if all(i in a for i in b):
   print("Yes I have all the elements but not sure about their order :( ")

I have tried all() or using counter() from collections module. I can't seem to figure it out how to check their order too.

Danny
  • 33
  • 6
  • If the first elements match, what else is left to do? If they don't what else is left to do? – Scott Hunter Dec 26 '21 at 18:38
  • Does this answer your question? [Checking if list is a sublist](https://stackoverflow.com/questions/35964155/checking-if-list-is-a-sublist) – sj95126 Dec 26 '21 at 18:40
  • @sj95126 - No, the solution there doesn't check order. You can test that on first test above (a and b) – Danny Dec 26 '21 at 18:46
  • @Danny: there are many solutions in that thread. Some do not check order and the comments reflect that. – sj95126 Dec 26 '21 at 18:47
  • Sublist already implies same order. So it's unclear what you're talking about. – no comment Dec 26 '21 at 18:49

3 Answers3

2

This will check all subList of length a and return True if a is found in b

Not sure about order :

def isSublist(a,b):
    #checking all unique elements and their count
    for i in set(a):
        if i not in b or a.count(i) > b.count(i):
             return False
    return True

Sure about order :

def isSublist(a,b):
    for i in range(len(b)-len(a)+1):
        if b[i:i+len(a)] == a:
            return True
    return False
THUNDER 07
  • 521
  • 5
  • 21
2

In most cases, when elements of lists has normal types, you can just convert them to str first and then do

"#".join(sublist) in "#".join(list)

Where # is a symbol that doesn't occur in list

Edit, as no comment pointed out, indeed there is one bug it that approach - if last sublists element is prefix of last lists element. Same with first element suffix. We can manage it by adding some kind of sentinel at the beggining/end, so correct solution would be

"#".join([""] + sublist + [""]) in "#".join([""] + list + [""])
kosciej16
  • 6,294
  • 1
  • 18
  • 29
  • 1
    `join` won't work if the list elements aren't `str` – match Dec 26 '21 at 18:48
  • @match I touched that in answer ;) The problem is sometimes simple `str` method can not be enough (e.g. for class with custom __eq__) that's why I provided last step of algorithm. – kosciej16 Dec 26 '21 at 18:51
1

You can use all() by performing the check for membership of a in b through an iterator on b:

a = [1,1,2]
b = [0, 1,1,1,2,1]

r = all(n in ib for ib in [iter(b)] for n in a)
print(r) # True

It will also find a match for items in the same relative order (that are not consecutive):

a=[1,2,1]
b=[1,2,3,1]
r = all(n in ib for ib in [iter(b)] for n in a)
print(r) # True

How it works:

  • every time n in ib is executed, the ib iterator advances up to the next matching value in b.
  • Going through all values of a will match items sequentially over the remainder of b after each match check
  • If ib is exhausted before getting to the end of a, then the elements aren't all present or their order doesn't match

If you are looking for consecutive matches, you can use the in operator on a generator that yields sublists of the corresponding length:

a = [1,1,2]
b = [0, 1,1,1,2,1]

r = a in (b[i:i+len(a)] for i in range(len(b)-len(a)+1))
print(r) # True
Alain T.
  • 40,517
  • 4
  • 31
  • 51
  • thanks for your answer and the explanation. I need to go through it at my pace as I am new to Python. – Danny Dec 28 '21 at 12:06