-2

I am trying to write a code that finds every instance in one list that does not start with an item in another list

I'm trying this:

list1 = ['1234', '2345', '3456', '4567']
list2 = ['1', '2']

for x in list1:
    for y in list2:
        if not x.startswith(y):
            print(x)

but it returns this:

1234
2345
3456
3456
4567
4567

Which is baffling to me because if I remove "not" it can find items in list1 that start with an item in list2 just fine. How can I write a code that accomplishes my goal?

ACan
  • 105
  • 1
  • 1
  • 7
  • 2
    I suggest using debugger and running your code step-by-step. Basically, you need to know the difference between `all` and `any`. – PM 77-1 Dec 01 '20 at 02:00
  • @ACan There are 6 output for 4 input, how is it possible? The answer to this question is your solution. – Shadowcoder Dec 01 '20 at 02:07
  • Related: [Check if a Python list item contains a string inside another string](https://stackoverflow.com/q/4843158/4518341) – wjandrea Dec 01 '20 at 02:19

4 Answers4

2

You can try this,

list1 = ['1234', '2345', '3456', '4567'] 
list2 = ['1', '2']
print( *[x for x in list1 if all([x[:len(l)]!=l for l in list2])],sep="\n")
Janith
  • 403
  • 6
  • 14
1

This is because your code prints the output if the value not start with either 1 or 2

Try this:

list1 = ['1234', '2345', '3456', '4567'] 
list2 = ['1', '2'] 
for x in list1:
    if not any([x.startswith(y) for y in list2]):
            print(x)
Shadowcoder
  • 962
  • 1
  • 6
  • 18
1

This is a purely logical problem. I'm not sure how to describe it clearly in English, so here's a table instead. Every True in the last column means that x will be printed in your code. I hope it clarifies how your code works.

for x in list1:
    for y in list2:
        print(x, y, not x.startswith(y))
1234 1 False
1234 2 True
2345 1 True
2345 2 False
3456 1 True
3456 2 True
4567 1 True
4567 2 True

The solution is to loop over list2 altogether and check the result using any or all:

for x in list1:
    if not any(x.startswith(y) for y in list2):
        print(x)
3456
4567
wjandrea
  • 28,235
  • 9
  • 60
  • 81
0

Try a for/else loop. The else will only execute if the loop isn't broken.

list1 = ['1234', '2345', '3456', '4567']
list2 = ['1', '2']

for x in list1:
    for y in list2:
        if x.startswith(y):
            break
    else:
        print(x)
luthervespers
  • 258
  • 1
  • 2
  • 10