Я долго обсуждал вопрос об этом, потому что подобные вопросы задавались здесь много раз. Но это достаточно уникально, чтобы дать преимущество сомнения. (Тем не менее, я не буду возражать, если другие проголосуют за закрытие.) Вот визуальное объяснение того, что происходит.
[0, 1, 2, 3, 4, 5, 6, 7, 8, 9] <- b = 0; remove? no
^
[0, 1, 2, 3, 4, 5, 6, 7, 8, 9] <- b = 1; remove? yes
^
[0, 2, 3, 4, 5, 6, 7, 8, 9] <- b = 3; remove? no
^
[0, 2, 3, 4, 5, 6, 7, 8, 9] <- b = 4; remove? yes
^
[0, 2, 3, 5, 6, 7, 8, 9] <- b = 6; remove? no
^
[0, 2, 3, 5, 6, 7, 8, 9] <- b = 7; remove? yes
^
[0, 2, 3, 5, 6, 8, 9] <- b = 9; remove? no
^
Поскольку больше никого нет, я попытаюсь ответить на другие ваши вопросы:
Почему не указана ошибка, указывающая, что базовый итератор изменяется?
Чтобы выдать ошибку без запрета многих совершенно допустимых конструкций цикла, Python должен был бы знать lot о том, что происходит, и он, вероятно, должен был бы получить эту информацию во время выполнения. Вся эта информация займет время для обработки. Это сделало бы Python намного медленнее, просто там, где скорость действительно имеет значение - петля.
Механики изменились по сравнению с более ранними версиями Python по отношению к этому поведению?
Короче, нет. Или, по крайней мере, я очень сомневаюсь в этом, и, конечно, он так себя вел с тех пор, как начал изучать Python (2.4). Честно говоря, я ожидаю, что любая простая реализация изменяемой последовательности будет вести себя именно так. Кто знает лучше, поправьте меня. (На самом деле, быстрый поиск документов подтверждает, что текст, который цитируется Mikola , находится в руководстве с версии 1.4 !)