Удалить повторяющуюся последовательность целых чисел из списка в 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 ответ:
Часть ответа: обнаружьте повторяющиеся последовательности.
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..