RifloSnake
RifloSnake

Reputation: 347

Find pattern of elements between multiple lists

Take these lists:

[545, 766, 1015]
[546, 1325, 2188, 5013]
[364, 374, 379, 384, 385, 386, 468, 496, 497, 547]

My actual pattern is just finding numbers that are ascending by one, only one from each list (For this example, would be 545, 546 and 547). After actually finding this exists, I want the first number in the sequence to be returned to me so I can continue with my other calculations.

Preferred code execution example:

>>>[12, 64, 135, 23]   # input lists
>>>[84, 99, 65]
>>>[66, 234, 7, 43, 68]

>>>[64, 65, 66]        # found numbers by said pattern.

>>>return 64

I have not thought of any function worthy to be written ...

Upvotes: 1

Views: 186

Answers (2)

mozway
mozway

Reputation: 260790

A series is valid only for all numbers in the first list only if n+1 is in the next list, n+2 in the one after etc.

You can use set operations and short-circuiting with all to make searching efficient:

lists = [[545, 766, 1015],
         [546, 1325, 2188, 5013],
         [364, 374, 379, 384, 385, 386, 468, 496, 497, 547],
        ]

sets = list(map(set, lists))

out = [x for x in lists[0] if all(x+i in s for i, s in enumerate(sets[1:], start=1))]

Output:

[545]

as a function:

def find_successive(lists):
    sets = list(map(set, lists[1:]))
    return [x for x in lists[0] if all(x+i in s for i, s in
                                    enumerate(sets, start=1))
           ]

find_successive([[12, 64, 135, 23],[84, 99, 65],[66, 234, 7, 43, 68]])
# [64]

find_successive([[12, 64, 135, 23],[84, 99, 65, 24],[66, 234, 7, 25, 43, 68]])
# [64, 23]

Alternative approach, still using sets for efficiency. Generate sets of the lists, removing 1 for the second list values, 2 for the third, etc. Then find the sets intersection:

def find_successive(lists):
    sets = [{x-i for x in l} for i,l in enumerate(lists)]
    return set.intersection(*sets)

# or, shorter syntax
def find_successive(lists):
    return set(lists[0]).intersection(*({x-i for x in l} for i, l in enumerate(lists[1:], start=1)))


find_successive([[12, 64, 135, 23],[84, 99, 65, 24],[66, 234, 7, 25, 43, 68]])
# {23, 64}

Upvotes: 2

Ricardo
Ricardo

Reputation: 691

def search(a,b,c):
    for val in a:
        if (val+1) in b and (val+2) in c:
            return val
print(search([545, 766, 1015],[546, 1325, 2188, 5013],[364, 374, 379, 384, 385, 386, 468, 496, 497, 547]))

Upvotes: -1

Related Questions