0

Let's say I have 2 lists:
a = [6,7,8,9,10]
b = [1,3,4,6,7,8,9,10]

I have a function that is used to find out if list a can be found in list b. If it is found, then it returns True. In my case it should return True because list a can be found at the end of list b. List a never changes and always contains the same numbers, whereas list b accepts numbers from the user and then uses sorted() method to sort numbers in ascending order. I should also add that the order does matter.

I have searched around and could find a subset method, which looks like this: set(a).issubset(set(b))) as well as using in method. Both of them did not work for me.

UPDATE: Using set(a).issubset(set(b))) for some reason always returns True. For example, if a = [1,1] and b = [0,1,2,3,4,5] then using subset method returns True, even though 1,1 cannot be found in b. I'm not looking if 1 is inside the list, I'm looking if 1,1 is inside the list.

Using in method when
a = [6,7,8,9,10]
b = [1,3,4,6,7,8,9,10] returns False.

6
  • Why didn't they work? Commented Nov 17, 2013 at 21:54
  • 4
    When you say they did not work, what do you mean? Did they not give the correct answer, or did they cause the program to error out? Can you show us what you are currently implementing? Commented Nov 17, 2013 at 21:54
  • 1
    You should look at the documentation for set. Every element in a set must be unique, so a = set([1,1]) only has the element 1, in it, and 1 is in [0,1,2,3,4,5] Commented Nov 17, 2013 at 22:01
  • but in set theory the set (1,1) is a subset of the set (1,2) as 1 == 1... so you're not looking for sets at all then. Commented Nov 17, 2013 at 22:01
  • 1
    When I asked "Can you show us what you are currently implementing?", I meant actually show your code. Simply stating that "using the in method when a = [6,7,8,9,10] and b = [1,3,4,6,7,8,9,10] returns False" doesn't explain how you actually implemented this. Maybe you have a syntax problem that we can help you resolve that you are unaware of. Commented Nov 17, 2013 at 22:04

6 Answers 6

2

You didn't say how important speed was. So I'd wrap the functionality in a class, so that you can hide the complications from the rest of your code if you need to get fancier later. Since

List a never changes and always contains the same numbers

it makes sense to pass a to the class constructor. Here's one way:

class ASearcher: def __init__(self, a): self.a = a def isin(self, b): a = self.a a0 = a[0] lena = len(a) i = 0 try: while 1: j = b.index(a0, i) # raises ValueError if not found if a == b[j: j+lena]: return True i = j+1 # start search over 1 position later except ValueError: return False 

Then, e.g.,

asearch = ASearcher([6,7,8,9,10]) print asearch.isin([1,3,4,6,7,8,9,10]) 

prints True.

There is no function in the standard library to do what you want here, so you need to roll your own. The class above implements a method that does the searching, in B, for the first element of A, "at C speed". It will probably be "fast enough" - maybe ;-)

Sign up to request clarification or add additional context in comments.

1 Comment

Really nice explanation. Other answers were also useful to me. Thank you everyone, the problem is now solved
1

If the values in a and b happen to be in the range 0-255, you can use this trick

>>> a = [6,7,8,9,10] >>> b = [1,3,4,6,7,8,9,10] >>> bytearray(a) in bytearray(b) True 

Comments

0

Here is a brute force way:

a = [6,7,8,9,10] b = [1,3,4,6,7,8,9,10] def check_if_in_list(a, b): for i in xrange(len(b) - len(a) + 1): if a == b[i : i + len(a)]: return True return False 

Result:

>>> check_if_in_list(a, b) True 

Comments

0

If I understand you, you're interested in knowing whether a is a contiguous subsequence of b. So:

>>> a = [6,7,8,9,10] >>> b = [1,3,4,6,7,8,9,10] >>> any(b[i:i+len(a)] == a for i in range(len(b)-len(a)+1)) True 

This isn't the most efficient approach, but it'll often be fast enough in practice.

Comments

0

Something you find useful

idx = -1 notfound = False for index, item in enumerate(b): if item == a[0]: idx = index if idx == -1: notfound = True for i in xrange(idx, len(a) + idx): if len(b) <= i or a[i - idx] != b[i]: notfound = True print "Not found: ", notfound 

Comments

0

You do not need to loop over each and every index. Just find the first element and then see of the remainder elements match.

You could do something along these lines:

a = [6,7,8,9,10] b = [1,3,4,6,7,8,9,10] def liAinliB(a, b): try: ind=b.index(a[0]) except ValueError: return False return b[ind:ind+len(a)]==a print(liAinliB(a, b)) 

Comments

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.