Почему Python пропускает элементы, когда я изменяю список при итерации по нему?

Если вы находитесь в среде разработки, попробуйте установить для домена cookie значение «127.0.0.1». Также для запроса и ответа установите для учетных данных значение true.

11
задан Joe 16 October 2018 в 07:40
поделиться

5 ответов

Это хорошо документированное поведение в Python, которое не должно изменять список, через который выполняется итерация. Попробуйте вместо этого:

for i in x[:]:
    x.remove(i)

[:] возвращает «срез» x , который содержит все его элементы и, таким образом, фактически является копией x .

32
ответ дан 3 December 2019 в 00:54
поделиться

Когда вы удаляете элемент и цикл for включает следующий индекс, вы затем пропускаете элемент.

Делай это задом наперед. Или, пожалуйста, укажите свою реальную проблему.

11
ответ дан 3 December 2019 в 00:54
поделиться

Почему бы вам просто не использовать:

x = []

Это, вероятно, потому что вы меняете тот же массив, что и вы повторяем.

Попробуйте ответ Криса-Джестера Янга, если хотите очистить массив.

3
ответ дан 3 December 2019 в 00:54
поделиться

Я думаю, в широком смысле говоря, что когда вы пишете:

for x in lst:
    # loop body goes here

под капотом, python делает что-то вроде этого:

i = 0
while i < len(lst):
    x = lst[i]
    # loop body goes here
    i += 1

Если вы вставите lst.remove (x) для тела цикла, возможно, тогда вы будете в состоянии понять, почему вы получаете результат, который вы делаете?

По сути, python использует движущийся указатель для перемещения по списку. Указатель начинается с указания на первый элемент. Затем вы удаляете первый элемент, тем самым делая второй элемент новым первым элементом. Затем указатель перемещается на новый второй - ранее третий - элемент. И так далее. (может быть понятнее, если вы используете [1,2,3,4,5] вместо [1,2,2,2,2] в качестве списка образцов)

4
ответ дан 3 December 2019 в 00:54
поделиться

Я согласен с Джоном Фухи относительно условия разрыва. Как предположил Крис Джестер-Янг, просмотр копии списка работает для метода remove (). Но если нужно использовать pop () определенные элементы, то, как упоминал Эрик, итерация в обратном порядке работает, и в этом случае операцию можно выполнить на месте. Например:

def r_enumerate(iterable):
    """enumerator for reverse iteration of an iterable"""
    enum = enumerate(reversed(iterable))
    last = len(iterable)-1
    return ((last - i, x) for i,x in enum)

x = [1,2,3,4,5]
y = []
for i,v in r_enumerate(x):
    if v != 3:
        y.append(x.pop(i))
    print 'i=%d, v=%d, x=%s, y=%s' %(i,v,x,y)


или с xrange:

x = [1,2,3,4,5]
y = []
for i in xrange(len(x)-1,-1,-1):
    if x[i] != 3:
        y.append(x.pop(i))
    print 'i=%d, x=%s, y=%s' %(i,x,y)
1
ответ дан 3 December 2019 в 00:54
поделиться
Другие вопросы по тегам:

Похожие вопросы: