Как удалить элементы из списка во время итерации?

Вы можете использовать этот парсер json для просмотра вашего контента в правильном формате.

Вы можете использовать этот код:

$json = json_decode($url,true);

//you can retrieve kind, tag, id by using

$kind = $json['kind'];
$id = $json['id'];

Здесь элементы сам будет иметь массив, который вы можете использовать

$items[] = $json['items'];

// you can retrieve the data inside the kind array

$kind_arr = $json['items'][0][]['kind'];

//similarly you can parse all the data

863
задан Ciro Santilli 新疆改造中心996ICU六四事件 28 February 2018 в 14:25
поделиться

8 ответов

Вы можете использовать понимание списка, чтобы создать новый список, содержащий только те элементы, которые вы не хотите удалять:

somelist = [x for x in somelist if not determine(x)]

Или, назначив срез somelist [:] , вы можете изменить существующий список, чтобы он содержал только те элементы, которые вам нужны:

somelist[:] = [x for x in somelist if not determine(x)]

Этот подход может быть полезен, если есть другие ссылки на somelist , которые должны отражать изменения.

Вместо понимания вы также можете использовать itertools . В Python 2:

from itertools import ifilterfalse
somelist[:] = ifilterfalse(determine, somelist)

или в Python 3:

from itertools import filterfalse
somelist[:] = filterfalse(determine, somelist)
791
ответ дан 19 December 2019 в 20:21
поделиться

Проблема состоит в том, что список имеет изменяемый объект

#+begin_src ipython :session alinbx :results output
mylist = list(range(8))
idx = 0
for i in mylist:
    print(f"i={i}, idx={idx}, mylist{[idx]}={mylist[idx]}, {mylist}")
    mylist.remove(i)
    idx += 1

#+end_src

#+RESULTS:
: i=0, idx=0, mylist[0]=0, [0, 1, 2, 3, 4, 5, 6, 7]
: i=2, idx=1, mylist[1]=2, [1, 2, 3, 4, 5, 6, 7]
: i=4, idx=2, mylist[2]=4, [1, 3, 4, 5, 6, 7]
: i=6, idx=3, mylist[3]=6, [1, 3, 5, 6, 7]

Как шаг idx вперед, mylist уменьшения также.

#+begin_src ipython :session alinbx :results output
mylist = list(range(8))
idx = 0
for i, e in enumerate(mylist):
    print(i, e)
    mylist.remove(e)

#+end_src

#+RESULTS:
: 0 0
: 1 2
: 2 4
: 3 6
0
ответ дан 19 December 2019 в 20:21
поделиться

Я думаю, что использование, в то время как и неинкремент при удалении элемента самый простой путь.

import random

def f(l, n):
    # n shall not pass
    idx = 0
    while idx < len(l):
        if l[idx] % 2 == n:
            del l[idx]
            continue
        idx += 1


res = [random.randrange(1, 50) for i in range(10000)]
f(res, 0)
f(res, 1)

В конце res должен быть [].

0
ответ дан 19 December 2019 в 20:21
поделиться

Для тех, кто любит функциональное программирование:

somelist[:] = filter(lambda tup: not determine(tup), somelist)

или

from itertools import ifilterfalse
somelist[:] = list(ifilterfalse(determine, somelist))
37
ответ дан 19 December 2019 в 20:21
поделиться
for i in range(len(somelist) - 1, -1, -1):
    if some_condition(somelist, i):
        del somelist[i]

Вам нужно вернуться назад, иначе это немного похоже на отпиливание ветки дерева, на которой вы сидите: -)

Пользователи Python 2: замените range на xrange , чтобы не создавать жестко заданный список

116
ответ дан 19 December 2019 в 20:21
поделиться

Вашим лучшим подходом для такого примера будет понимание списка

somelist = [tup for tup in somelist if determine(tup)]

В случаях, когда вы делаете что-то более сложное, чем вызов функции define , я предпочитаю создать новый список и просто добавляя к нему, когда я иду. Например,

newlist = []
for tup in somelist:
    # lots of code here, possibly setting things up for calling determine
    if determine(tup):
        newlist.append(tup)
somelist = newlist

Копирование списка с помощью remove может сделать ваш код немного чище, как описано в одном из ответов ниже. Вы определенно не должны делать это для очень больших списков, поскольку это включает в себя сначала копирование всего списка, а также выполнение операции O (n) remove для каждого удаляемого элемента, что делает это Алгоритм O (n ^ 2) .

for tup in somelist[:]:
    # lots of code here, possibly setting things up for calling determine
    if determine(tup):
        newlist.append(tup)
48
ответ дан 19 December 2019 в 20:21
поделиться

Ответы, предполагающие понимание списка ПОЧТИ верны - за исключением того, что они создают полностью новый список, а затем дают ему то же имя, что и старый список, они НЕ изменяют старый список на месте. Это отличается от того, что вы делали бы путем выборочного удаления, как в @ Предложение Леннарта - это быстрее, но если доступ к вашему списку осуществляется через несколько ссылок, это означает, что вы просто переустанавливаете одну из ссылок и НЕ изменение самого объекта списка может привести к незаметным катастрофическим ошибкам.

К счастью,

566
ответ дан 19 December 2019 в 20:21
поделиться

Вам необходимо взять копию списка и сначала перебрать ее, иначе итерация завершится неудачно, что может привести к неожиданным результатам.

Например (зависит от типа списка) :

for tup in somelist[:]:
    etc....

Пример:

>>> somelist = range(10)
>>> for x in somelist:
...     somelist.remove(x)
>>> somelist
[1, 3, 5, 7, 9]

>>> somelist = range(10)
>>> for x in somelist[:]:
...     somelist.remove(x)
>>> somelist
[]
279
ответ дан 19 December 2019 в 20:21
поделиться
Другие вопросы по тегам:

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