Удалить повторяющуюся последовательность целых чисел из списка в Python


У меня есть список целых чисел, из которых мне нужно удалить повторяющиеся последовательности, и логика делает мою голову.

Я пытался изменить Этот на то, что мне нужно, однако это возвращает только одно число, относящееся к длине повторяющейся последовательности, и оно отсчитывается только от начального целого числа.

Это все, что я успел сделать:

def findRep(rmRepList):
    #Array to hold [starting position, length] of repeating sequences
    repList = []
    #For each industry listed
    for industry in rmRepList:
        #Maximum starting position
        maxStartPos = len(industry)-2
        #For each possible starting point of repetition
        for start in range(1,maxStartPos):
            #Limit on how long the repetition can be
            maxLen = math.ceil((len(industry)-start)/2)

            #For each possible length (2 because already canceled out repeating resources in genAllLoop)
            for i in range(2,maxLen):
                #If the next 'i' integers repeat
                if industry[start:i+start] is industry[i+start:2*i+start]:
                    repList = [start,i]
                    industry = rmRep(repList, industry)

                #If reached end of list
                if 2*i+start+1 == len(industry):
                    #End loop
                    break

def rmRep(rmProp, loop):
    #Sequence of resources to drop
    rmSeq = [loop[rmProp[0]:rmProp[0]+rmProp[1]]]
    #Debugging statement
    print(rmSeq)
    loop.remove(rmSeq)
    return(loop)name = username_entry.get()

RmRepList - это список списков, содержащий каждый список, который мне нужно проанализировать.

Так, например, если задан список

rmRepList = [[0,1,2,1,2,1,0],[0,1,2,1,2,1,2,3,4,5,3,4,5,6,0]]

Мне нужно, чтобы он вернулся [[0,1,2,1,0], [0,1,2,3,4,5,6,0]]

Прямо сейчас код даже не достигает подпрограммы rmRep. У меня ужасное чувство, что я все делаю неправильно. Мне не нравится, что мне нужно так много циклов в коде, тем более что фактические списки, которые я должен проанализировать, имеют сотни цифр. Есть ли более простой способ сделать это?


EDIT: если это поможет, я могу гарантировать, что списки не будут повторять одно целое число снова и снова (например, [0,0,0,1,0] не будет случаться).

Кроме того, первое и последнее число в списках всегда будет одним и тем же.
1 4

1 ответ:

Часть ответа: обнаружьте повторяющиеся последовательности.

listA = [0,1,2,1,2,1,2,3,4,5,3,4,5,6,0]
listB = [0,1,2,1,2,1,0]

def get_repeated_seq(seq, start, length):
    ref = seq[start:start+length]
    #print("Ref", ref)
    for pos in range(start+length, len(seq)-length):
        compare = seq[pos:pos+length]
        #print("Pos", pos, compare)
        if compare == ref:
            print("Found", ref, "at", pos)
            return pos
    return False

def get_repeated_seqs(seq):
    for size in reversed(range(2, len(seq)/2)):
        for pos in range(0, len(seq)-size):
            print("Check rep starting at pos %s for size %s" % (pos, size))
            get_repeated_seq(seq, pos, size)

print(get_repeated_seqs(listA))

Затем вы можете удалить их в соответствии с вашей стратегией удаления (largests ? маленькие дети ?)

EDIT : чтобы было ясно, что это работает (и добавление некоторого удаления к тому же времени)

listA = [0,1,2,1,2,1,2,3,4,5,2,1,3,4,5,2,1,6,0]
listB = [0,1,2,1,2,1,0]

def get_repeated_seq(seq, start, length):
    ref = seq[start:start+length]
    #print("Ref", ref)
    for pos in range(start+length, len(seq)-length):
        compare = seq[pos:pos+length]
        #print("Pos", pos, compare)
        if compare == ref:
            #print("Found", ref, "at", pos)
            return pos, length
    return False

def get_repeated_seqs(seq):
    reps = []
    for size in reversed(range(2, len(seq)/2)):
        for pos in range(0, len(seq)-size):
            #print("Check rep starting at pos %s for size %s" % (pos, size))
            rep = get_repeated_seq(seq, pos, size)
            if rep:
                reps.append(rep)
    return reps

def remove_repeated_seqs(seq, reps):
    # need to backup seq ?
    for rep in reps:
        overlaps = False
        for pos in range(rep[0], rep[0]+rep[1]):
            if seq[pos] == "*":
                overlaps = True
        if not overlaps:
            for pos in range(rep[0], rep[0]+rep[1]):
                seq[pos] = "*"
    out = []
    for item in seq:
        if item != "*":
            out.append(item)
    return out


reps = get_repeated_seqs(listB)
rem = remove_repeated_seqs(listB, reps)
#print(rem)
print(rem==[0,1,2,1,0])

reps = get_repeated_seqs(listA)
rem = remove_repeated_seqs(listA, reps)
#print(rem)
print(rem==[0,1,2,3,4,5,6,0])

Выводит True и True :)

EDIT2: нет -1, чтобы перейти к концу списка в цикле for range..