Почему я продолжаю получать ошибку индекса при попытке удаления, когда замена на символ работает нормально?

Программируя newb/python newb, моя работа супер нетребовательна, поэтому я нашел много свободного времени, чтобы научиться кодировать.

Я работаю над этой проблемой rosalind.info.

Вот мой код до сих пор:

# -*- coding: utf-8 -*-
"""
Created on Thu Jan 21 09:01:51 2016

@author: aseyedian
"""
codon = ''

q=0
with open('rosalind_prot.txt', 'r') as prot:
    bb = list(prot.read())

mylist = []   
for i in range(len(bb)):
     mylist.append(bb[i])


for i in range(0, len(bb),3):
    mylist[i] = [''.join(mylist[i:i+3])]

for i in range(1, len(mylist), 3):
    del mylist[i]

for i in range(2, len(mylist), 3):
    del mylist[i]

print mylist
#This is to create a list of codons which then are translated into amino acids

по какой-то причине,

for i in range(1, len(mylist), 3):
        del mylist[i]

возвращает ошибку IndexError (назначение списка вне диапазона), однако

for i in range(1, len(mylist), 3):
        mylist[i] = 'k'

Превращает каждого второго члена списка в букву "к". Почему это?

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

Например: ['A', 'U', 'G'] -> [['AUG'], 'U', 'G'] -> ['AUG'], ['GCC' (следующий кодон)], так далее...

4 ответа

Решение

Не копировать bb в mylist а затем попробуйте изменить mylist на месте. Просто скопируйте из bb в mylist:

bb = 'AUGGCCAUGGCGCCCAGAACUGAGAUCAAUAGUACCCGUAUUAACGGGUGA'
mylist = []
for i in range(0, len(bb), 3):
    mylist.append(bb[i:i+3])
print mylist

Выход:

['AUG', 'GCC', 'AUG', 'GCG', 'CCC', 'AGA', 'ACU', 'GAG', 'AUC', 'AAU', 'AGU', 'ACC', ' CGU ',' AUU ',' AAC ',' GGG ',' UGA ']

Когда вы удаляете элемент из списка, у него теперь меньше элементов. Следовательно, список в позиции его длины - 1 больше не существует. Допустим, у вас есть список длиной 4. Как только вы попытаетесь получить доступ к списку в позиции 2, вы уже удалили 2 элемента, и в списке осталось только 2 элемента. Теперь в списке ничего нет в позиции 2. Вместо этого просто del mylist[0],

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

Например,

mylist = ['A', 'B', 'C', 'D', 'E']

Ваш код предполагает удалить "B" и "E" (номера 1 и 4) из списка,

for i in range(1, len(mylist), 3):
    del mylist[i]

Однако после того, как первый проход "B" был удален, список стал ["A", "C", "D", "E"]. На данный момент в этом списке всего 4 элемента, а элемент 4 больше не существует.

То, что вы хотите сделать, это получить список, который содержит элементы #0, #3, #6, ... из исходного списка. Вы можете просто использовать фрагмент списка следующим образом:

print mylist[0::3]

Рассмотрим список длины 3:

l = ['1', '2', '3']

Нет, мы перебираем это, используя range(len(l)):

for i in range(len(l)):
    print('i =', i)
    print('l[i] =', l[i])
    del l[i]

Это результат:

i = 0
l[i] = 1
i = 1
l[i] = 3
i = 2
------------------------------------
IndexError
<ipython-input-6-ab3e74355e73> in <m
      1 for i in range(len(l)):
      2     print('i =', i)
----> 3     print('l[i] =', l[i])
      4     del l[i]

IndexError: list index out of range

Итак, в первой итерации вы удаляете первый элемент, который '1', это оставляет список как ['2', '3']

Затем мы удаляем элемент секунд списка, который '3' сейчас и список становится ['2', ],

В итерации трети, i = 2 но в списке есть только один элемент, поэтому мы получаем ошибку индекса.

Решение будет сделать это в обратном порядке:

for i in reversed(range(1, len(mylist), 3)):
        del mylist[i]
Другие вопросы по тегам