Search for a sequence from a list in another list

2

I'm trying to find a sequence from a list in another list. But I do not understand why my exit is "no".

all: is not a solution because it returns true even if the elements are not in order

set: is not a solution because I need the repeated elements

Script:

fruits = ['banana', 'grape', 'blueberry', 'kiwi', 'raspberry', 'coconut', 'apple']
colors = ['yellow', 'wine', 'blue', 'green', 'red', 'brown', 'red']

sequence = ['blue', 'green', 'red']

if sequence in colors:
    print("yes")
else:
    print("no")

Output:

  

no

    
asked by pitanga 14.09.2017 в 16:04
source

3 answers

2

What you can do is convert those array into string and then compare the sequence

colors = ['yellow', 'wine', 'blue', 'green', 'red', 'brown', 'red']
sequence = ['blue', 'green', 'red']


strColors = str(colors).strip("[]")
strSequence = str(sequence).strip("[]")

if strSequence in strColors:
    print("yes")
else:
    print("no")

Result:

>>>yes

Demo online

    
answered by 14.09.2017 / 16:11
source
3

From what you say, you want to find a certain sequence of words in another, in the same order of appearance. You have already done a good research and you have ruled out some options that do not help for this. Well, I can think of a super simple form, which conceptually is similar to the one given to you by lois6b: transform the lists into strings and compare them:

fruits = ['banana', 'grape', 'blueberry', 'kiwi', 'raspberry', 'coconut', 'apple']
colors = ['yellow', 'wine', 'blue', 'green', 'red', 'brown', 'red']
sequence = ['blue', 'green', 'red']

if ",".join(sequence) in ",".join(colors):
  print("Si")

Note that when converting to a string we add a separator between each item in the list, this is to avoid some case like: ['blu', 'egreen', 'red'] , also take into account this delimiter, it should not be a character that appears in the values but this algorithm could eventually fail.

Another interesting way is going through the list and making "slice" of the size we want to find, in fact it is the safest logic, but it is also slower than the previous option.

if any(sequence == colors[i:i+len(sequence)] for i in range(len(colors) - 1)):
  print("Si")
    
answered by 14.09.2017 в 16:41
2

Without making it complicated, you create a function to compare two lists:

def compare(lst1, lst2, ini=0):
    n = len(lst2)
    return lst1[ini:ini+n] == lst2

The variable ini allows you to compare the list lst2 from an element of lst1 . So, for example, with ini=0 we would compare from the first element of lst1 .

To achieve our goal, just go through the entire list and make comparisons:

any(compare(colors, sequence, i) for i in range(len(colors)))

It can be done better. Instead of comparing all the positions, we can reduce the comparisons to the positions in the first list where we find the first element of the second list, sequence[0] . You can use the list.index(x) method, but it is somewhat cumbersome to work with it when you want to get all the elements. It is better to make a function that gives us all the matching positions:

def indexes(lst, x):
    return (i for (i,y) in enumerate(lst) if x==y)

In this way, the verification would be much more optimized:

any(compare(colors, sequence, i) for i in indexes(colors, sequence[0]))
    
answered by 15.09.2017 в 02:59