Цикл по списку несколько раз
Можно ли перебирать список несколько раз? в основном у меня есть список строк, и я ищу самую длинную суперструну. Каждая из строк в списке имеет некоторое перекрытие по меньшей мере на половину их длины, и все они имеют одинаковый размер. Я хочу посмотреть, добавляется ли суперструна, которую я добавляю в начало, с или заканчивается с каждой из последовательностей в списке, и когда я найдите совпадение, которое я хочу добавить, чтобы добавить этот элемент в мою суперструну, удалите элемент из списка, а затем повторяйте его снова и снова, пока мой список не станет пустым.
sequences=['ATTAGACCTG','CCTGCCGGAA','AGACCTGCCG',''GCCGGAATAC']
halfway= len(sequences[0])/2
genome=sequences[0] # this is the string that will be added onto throughout the loop
sequences.remove(sequences[0])
for j in range(len(sequences)):
for sequence in sequences:
front=[]
back=[]
for i in range(halfway,len(sequence)):
if genome.endswith(sequence[:i]):
genome=genome+sequence[i:]
sequences.remove(sequence)
elif genome.startswith(sequence[-i:]):
genome=sequence[:i]+genome
sequences.remove(sequence)
'''
elif not genome.startswith(sequence[-i:]) or not genome.endswith(sequence[:i]):
sequences.remove(sequence) # this doesnt seem to work want to get rid of
#sequences that are in the middle of the string and
#already accounted for
'''
это работает, когда я не использую окончательное утверждение elif и дает правильный ответ ATTAGACCTGCCGGAATAC. Однако, когда я делаю это с большим списком строк, у меня все еще остаются строки в списке, который я ожидал оставить пустым. Кроме того, последний цикл даже необходим, если я ищу только строки для добавления на передней и задней части суперструны (геном в моем коде).
2 ответа
Попробуй это:
sequences=['ATTAGACCTG','CCTGCCGGAA','AGACCTGCCG','GCCGGAATAC']
sequences.reverse()
genome = sequences.pop(-1) # this is the string that will be added onto throughout the loop
unrelated = []
while(sequences):
sequence = sequences.pop(-1)
if sequence in genome: continue
found=False
for i in range(3,len(sequence)):
if genome.endswith(sequence[:i]):
genome=genome+sequence[i:]
found = True
break
elif genome.startswith(sequence[-i:]):
genome=sequence[:i]+genome
found = True
break
if not found:
unrelated.append(sequence)
print(genome)
#ATTAGACCTGCCGGAATAC
print(sequences)
#[]
print(unrelated)
#[]
Я не знаю, гарантировано ли, что у вас не будет нескольких несвязанных последовательностей в одном пакете, поэтому я допустил несвязанные. Если это не нужно, не стесняйтесь удалить.
Обработка удаления Python с фронта list
очень неэффективно, поэтому я перевернул список и потянул со спины. Обращение может не потребоваться в зависимости от полных данных (это с данными вашего примера).
Я выскочил из sequences
list
в то время как есть последовательности, доступные, чтобы избежать удаления элементов из list
перебирая это. Затем я проверяю, находится ли он уже в конечном геноме. Если это не так, я иду на проверку endswith
/ beginswith
чеки. Если совпадение найдено, нарежьте его на геном; установить найденный флаг; вырваться из for
петля
Если последовательность еще не содержится и частичное совпадение не найдено, она помещается в unrelated
Вот так я и решил ее, я понял, что все, что вам нужно сделать, это выяснить, какая строка является началом суперструны, так как мы знаем, что последовательности имеют перекрытие 1/2 или больше, я нашел, какая половина не была 't содержится в любой из последовательностей. Отсюда я зацикливал список на количество раз, равное длине списка, и искал последовательности, в которых конец генома соответствовал началу соответствующей последовательности. Когда я нашел это, я добавил последовательность в геном (суперструну), а затем удалил эту последовательность и продолжил перебирать список. При работе со списком из 50 последовательностей, имеющих длину 1000, для запуска этого кода требуется около.806441
def moveFirstSeq(seqList): # move the first sequence in genome to the end of list
d={}
for seq in seqList:
count=0
for seq1 in seqList:
if seq==seq1:
pass
if seq[0:len(seq)/2] not in seq1:
count+=1
d[seq]= count
sorted_values=sorted(d.values())
first_sequence=''
for k,v in d.items():
if v==sorted_values[-1]:
first_sequence=k
seqList.remove(first_sequence)
seqList.append(first_sequence)
return seqList
seq= moveFirstSeq(sequences)
genome = seq.pop(-1) # added first sequence to genome and removed from list
for j in range(len(sequences)): # looping over the list amount of times equal to the length of the sequence list
for sequence in sequences:
for i in range(len(sequence)/2,len(sequence)):
if genome.endswith(sequence[:i]):
genome=genome+sequence[i:] # adding onto the superstring and
sequences.remove(sequence) #removing it from the sequence list
print genome , seq