Форум сайта python.su
0
Приветствую.
Сразу скажу, что прежде чем сюда писать прочел соответствующую главу Бизли.
Ответа на мой вопрос, там не нашел.
Вобщем столкнулся я с непонятным для меня поведением for, а имено. Если преберать for(м) последовательность и при каждой итерации удалять из этого объекта возвращаемое значение.
То ощущение что фор бежит через 1
Я понимаю что, влюбом случае такие вещи нужно делать с копией объекта,
но всеже почему он так себя ведет?
In [87]: a = [1,2,3,4,5] In [88]: [a.pop(a.index(x)) for x in a] Out[88]: [1, 3, 5] In [89]: a Out[89]: [2, 4] In [90]: a = [1,2,3,4,5] In [91]: for x in a: print a.pop(a.index(x)) 1 3 5 In [92]: a Out[92]: [2, 4]
Офлайн
568
Я Бизли не читал, попробую объяснить на пальцах.
Как Вы думаете, как внутри питона происходит перебор списка?
Я тоже не знаю как, но давайте предположим, что по индексу.
То есть вместо
for i in lst:
for (int i; i<len(lst); i++) { lst[i] }
Ага, пятёрка вообще выпадает из перебора, потому что она была пятой, и цикл её показал бы на пятой
иттерации, но она теперь стала четвертой и извлекается lst[4], но цикл то извлекает lst[5], а там у нас УЖЕ шестёрка
Отредактировано FishHook (Ноя. 16, 2013 12:44:43)
Офлайн
0
FishHookДа наверно Вы правы.
Ну то есть классический цикл. Что же происходит, если мы в процессе перебора удаляем элементы?
Мы говорим питону, перебирай от первого элемента до последнего, питон циклом извлекает элементы 1й, 2й, 3й, и тут казалось бы 4й, но! четвертый элемнт Вы удалили, и его место занял пятый! Питон об этом ничего не знает, он продолжает извлекать по индексу
Смотрите
1,2,3,4,5,6
[a.pop(a.index(x)) for x in a]
FishHook
Не удаляйте элементы из списка в цикле. Никогда.
Отредактировано soln (Ноя. 16, 2013 16:39:08)
Офлайн
568
solnДа проще всё! Вместо того, чтобы удалять элементы, вы их просто не добавляйте. То есть мы делаем перебор по коллекции, и все элементы добавляем в другую коллекцию кроме тех, которые у нас “плохие”.
Это поняно. Если надо изменить список в цикле пользуюсь либо поверхносной копией либо copy.deepcopy
a = [1, 2, 3, 4] a = filter(lambda x: x%2, a)
Офлайн
0
FishHookХм. Аведь и вправду. Спасибо.
Вместо того, чтобы удалять элементы, вы их просто не добавляйте. То есть мы делаем перебор по коллекции, и все элементы добавляем в другую коллекцию кроме тех, которые у нас “плохие”.
Офлайн
36
FishHookДа можно удалять элементы вцикле, нет в этом ничего ужасного, просто двигаться по списку нужно от конца к началу.
Не удаляйте элементы из списка в цикле. Никогда.
Офлайн