-2

I wrote the function to find list A is in List B, the code as below:

def isinlist(l1,l2):
    flag=1
    for i in range(0,len(l1)+1):
        if l1[i] not in l2:
            flag = 0
    return flag
a1 = ['hello','hi','123']
a2 = ['no worry','hello','hi','123'' ]# f1 = isinlist() 
print(isinlist(a1,a2)) 

it show the error as below

IndexError: list index out of range

I thought the error come from l1 and l2 wasn't defined range in the function? Can someone help advise on this ?

thangvc91
  • 323
  • 2
  • 10

4 Answers4

0

The error you get already gives you a hint what is going wrong. Simply remove the +1 in range(0, len(l1)+1). Otherwise the function tries to access an index in the array, which is not defined.

def isinlist(l1,l2):
    flag=1
    for i in range(0,len(l1)):
        if l1[i] not in l2:
            flag = 0
    return flag

or what I would prefer (since range() starts at 0 from default)

def isinlist(l1,l2):
    flag=1
    for i in range(len(l1)):
        if l1[i] not in l2:
            flag = 0
    return flag
Maik Hasler
  • 1,064
  • 6
  • 36
0

the issue id in the line

for i in range(0,len(l1)+1):

in this loop i will eventually be larger than the length of l1 and thus l1[i] will be out of range

instead use

for i in range(len(l1)):

(range() starts at 0 by default)

Patrick
  • 1,189
  • 5
  • 11
  • 19
0

Just remove the +1 from for i in range(0,len(l1)+1): and you are good to go:

def isinlist(l1,l2):
    flag=1
    for i in range(0,len(l1)):
        if l1[i] not in l2:
            flag = 0
    return flag

a1 = ['hello','hi','123']
a2 = ['no worry','hello','hi','123' ] 
print(isinlist(a1,a2)) 

To find elements in list2 that are not in list1:

def contains(l1, l2):
    not_in__list_value=[]
    for i in range(len(l2)-len(l1)+1):
        for j in range(len(l1)):
            if l2[i+j] != l1[j]:
                not_in__list_value.append(l2[i+j] )
                break
        else:
            return not_in__list_value
    return not_in__list_value
a1 = ['hello','hi','123']
a2 = ['no worry','hello','hi','123' ]
f1 = contains(a1,a2)  
print("value that not in list1 ",f1)
Tomerikoo
  • 18,379
  • 16
  • 47
  • 61
Vector_07
  • 16
  • 2
0

I noticed that previous answers were not really pythonic and also checking only the presence of the elements.

Since you are learning python you definitely need to see how a pythonic solution would look like:

def is_in_list(left, right):
    """Returns true if all elements of left list are present also on right"""
    return set(left).issubset(set(right))

Please note that we are using snake_case to separate words and also the super power of sets.

Another pythonic way to achieve this, suggested by @Tomerikoo, which is more memory efficient:

def is_in_list(left, right):
    """Returns true if all elements of left list are present also on right"""
    return all(x in right for x in left).
Florin C.
  • 593
  • 4
  • 13
  • 1
    Or simply `all(x in l2 for x in l1)` – Tomerikoo Mar 02 '22 at 16:27
  • So true. "Simple is better than complex" – Florin C. Mar 02 '22 at 16:29
  • I wasn't sure if to mention it in the comment because I'm not completely sure it's true, but I think it is also more efficient than the set. It only iterates on `l1` once (or even less if there's short-circuiting) and no extra memory. You create two sets which means iterating over both of them and assigning memory for the sets – Tomerikoo Mar 02 '22 at 16:33
  • 1
    I can say that the _set_ version has the downside of duplicating both list elements in the new sets but it has a performance upside, since it avoids checking repeated elements. Think ["a", "a", "a"] in ["a", "b", "c"]. Anyway, for the learning opportunity both (there may be more) solutions worth to be noted. – Florin C. Mar 02 '22 at 16:38
  • I agree. Feel free to add it to your answer :) I'm not going to post it – Tomerikoo Mar 02 '22 at 16:40