1

I have a list of numbers, for example:

list= [1, 2, 4, 1, 2, 4, 1, 2, 4]

You can see the obvious repeating pattern of 1,2,4

I'm trying to find a way to go through that list to determine the cycle and it's length. The numbers vary every time in my program. So for example, the list that I give, I want it to output 3, which is the length of the pattern.

I tried comparing the items together, but ultimately couldn't figure out a way to do it efficiently without going out of the list index every time, because I was just looking for when a number repeated in the sequence. The problem with that was that the pattern could be something like 2 2 1, in which case i would have outputted 2 as the pattern length, when it was actually 3.

Sorry for the lack of information, I'm lost as to how to do this so I don't have much sample code to show.

2
  • can you assume that each cycle fully iterates? like is [1,2,3,1,2,3,1,2,3,1] a valid list? Commented Nov 26, 2015 at 0:34
  • Are you providing a pattern and getting number of occurrences or looking for a pattern and number of occurrences? Commented Nov 26, 2015 at 1:30

3 Answers 3

1

You can use a generator function to split your list into chunks.

>>> def gen(lst, pat):
...     size = len(pat)
...     size_l = len(lst)
...     for i in range(0, size_l, size):
...         yield lst[i:i+size]
... 
>>> lst = [1, 2, 4, 1, 2, 4, 1, 2, 4]
>>> pat = [1, 2, 4]
>>> len(list(gen(lst, pat)))
3

Also don't use "list" as variable's name it will shadow the built-in listclass

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

Comments

0

How about this?

def find_sub(lst):
    return next(sub for sub in range(len(lst), 0, -1)
                    if lst == mylist[:sub] * (len(lst) / sub))

find_sub([1, 2, 4, 1, 2, 4, 1, 2, 4]) # returns 3
find_sub([1, 2, 1, 2, 1, 2, 1, 2]) # returns 2
find_sub([1, 1, 1]) # returns 1
find_sub([1, 2, 3]) # returns 3
find_sub([1, 2, 3, 1, 2, 3, 1]) # returns 7

Comments

0

Returns the length of the pattern it has found or None if it can't find a pattern that repeats at least once.

def GetPattern(lst:list) -> list:
    lstLen = len(lst)
    i = 1
    while i < (lstLen - (lstLen % 2))//2:
        tar = lst[:i]
        d = lstLen % i

        if any([not tar == lst[i*a:i*(a+1)] for a in range(1, (lstLen - d)//i)]):
            i += 1
            continue
        elif not d == 0 and not tar[:d] == lst[-1*d:]:
            i += 1
            continue
        else:
            return len(tar)
    return None

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.