Вы перебираете список (drugs
), и внутри цикла вы удаляете элементы из того же списка.
Когда цикл for
выполняется над повторяемым объектом, Python сохраняетувеличивая внутреннюю переменную «index», которая помогает Python отслеживать текущий элемент списка, в котором мы находимся.
Внутри цикла, скажем, вы удалили элемент с index = 3. Теперь,остальная часть списка (элементы, которые вы еще не перебрали) сместится на одно место.Элемент, который ранее присутствовал в индексе 4, теперь будет присутствовать в индексе 3, освобожденном удаленным элементом.Чтобы обработать этот сдвинутый элемент в следующей итерации, внутренняя переменная «index» должна еще раз принять значение 3 для следующей итерации.Но Python увеличивает индексную переменную с 3 до 4 для следующей итерации, как это обычно бывает с одной итерации в другую.В результате элемент, следующий непосредственно за удаленным элементом, не будет проверен / обработан телом вашего цикла for (поскольку индекс будет равен 4, а не 3), и, следовательно, он не будет удален, даже если он соответствует критериям удаления..
Несколько решений
Существует несколько методов, предложенных для "безопасного" удаления, в этом потоке .
IЯ выбрал мой любимый из них и реализовал его для вашего кода ниже:
correction = {u'drug.ind': u'Necrosis', "date": "exp"}
drugs = [[u'drug.aus', u'Necrosis'], [u'drug.nz', u'Necrosis'], [u'drug.uk', u'Necrosis'],
[u'drug.ind', u'Necrosis'], [u'cheapest', u'drug.ind'], [u'date', u'']]
if correction and drugs:
for i,x in correction.items():
for j in range(len(drugs)-1, -1, -1):
if len(i.split(".")) > 1: # need to do the operation only for drugs which is always given in this format
if x == drugs[j][1]:
drugs.pop(j)
print(drugs)
Вывод этого:
[['cheapest', 'drug.ind'], ['date', '']]
Важнейшим аспектом этого решения являетсялиния for j in range(len(drugs)-1, -1, -1)
.Сейчас мы перебираем индексы вместо позиций по этим индексам.И мы перебираем индексы в обратном порядке (что фактически означает, что мы косвенно обрабатываем список в обратном порядке).