Home > Net >  Structural pattern matching python - match at any position in sequence
Structural pattern matching python - match at any position in sequence

Time:09-04

I have a list of objects, and want to check if part of the list matches a specific pattern.

Consider the following lists:

l1 = ["foo", "bar"]
l2 = [{1, 2},"foo", "bar"]
l3 = ["foo", "bar", 5]
l4 = [{1,2},"foo", "bar", 5, 6]

How would I match the sequence ["foo", "bar"] in all the different cases?

My naive idea is:

match l4:
    case [*_, "foo", "bar", *_]:
        print("matched!")

Unfortunately this is a SyntaxError: multiple starred names in sequence pattern. The issue is, that I don't know how many elements are leading and trailing the pattern.

CodePudding user response:

def struct_match(lst_target, lst_pattern):
    for i in range(len(lst_target)-(len(lst_pattern)-1)):
        if lst_target[i:i len(lst_pattern)] == lst_pattern:
            print('matched!')
l1 = ["foo", "bar"]
l2 = [{1, 2},"foo", "bar"]
l3 = ["foo", "bar", 5]
l4 = [{1,2},"foo", "bar", 5, 6]
l5 = [{1,2},"foo", "baz", "bar", 5, 6]

patt = ["foo", "bar"]

struct_match(l1, patt)
struct_match(l2, patt)
struct_match(l3, patt)
struct_match(l4, patt)
struct_match(l5, patt)


# outputs

matched!
matched!
matched!
matched!

PS: I just found a beautiful recursive solution here (recursion is always beautiful... if your list is not too long)

CodePudding user response:

Try this:

l1 = ["foo", "bar"]
l2 = [{1, 2},"foo", "bar"]
l3 = ["foo", "bar", 5]
l4 = [{1,2},"foo", "bar", 5, 6]

def locater(lst):
    trigger = False 
    i = 0
    while i < len(lst)-1:
        if l1[0] == lst[i] and l1[1] == lst[i 1]:
            trigger = True
            break
    return print('The pattern matches')
        

locater(l3)
  • Related