Python: удаление элемента списка при итерации по списку [дубликат]
этот вопрос уже есть ответ здесь:
Я перебираю список элементов в Python, делаю некоторые действия над ним, а затем удаляю их, если они соответствуют определенным критериям.
for element in somelist:
do_action(element)
if check(element):
remove_element_from_list
что я должен использовать вместо remove_element?
У меня есть видел подобные вопросы, но заметил наличие части do_action, которая должна быть выполнена для всех элементов и, таким образом, исключает решение с помощью фильтров.
9 ответов:
вы всегда можете перебирать копию списка, оставляя вам возможность изменять оригинал:
for item in list(somelist): ... somelist.remove(item)
чтобы соответствовать этим критериям: изменить исходный список на месте, нет копий списка, только один проход,работает, традиционным решением является итерация назад:
for i in xrange(len(somelist) - 1, -1, -1): element = somelist[i] do_action(element) if check(element): del somelist[i]бонус: не
len(somelist)на каждой итерации. Работает на любой версии Python (по крайней мере, до 1.5.2) ... s/xrange/ range / for 3.Х.обновление: если вы хотите повторить вперед, это возможно, просто сложнее и уродливее:
i = 0 n = len(somelist) while i < n: element = somelist[i] do_action(element) if check(element): del somelist[i] n = n - 1 else: i = i + 1
for element in somelist: do_action(element) somelist[:] = (x for x in somelist if not check(x))Если вам действительно нужно сделать это за один проход без копирования списка
i=0 while i < len(somelist): element = somelist[i] do_action(element) if check(element): del somelist[i] else: i+=1
вы все еще можете использовать фильтр, перемещая во внешнюю функцию модификацию элемента (повторяя только один раз)
def do_the_magic(x): do_action(x) return check(x) # you can get a different filtered list filter(do_the_magic,yourList) # or have it modified in place (as suggested by Steven Rumbalski, see comment) yourList[:] = itertools.ifilter(do_the_magic, yourList)
другой способ сделать это:
while i<len(your_list): if #condition : del your_list[i] else: i+=1Итак, вы удаляете элементы бок о бок при проверке
можно сделать генератор, который возвращает все, что не снято:
def newlist(somelist): for element in somelist: do_action(element) if not check(element): yield element
почему бы не переписать его, чтобы быть
for element in somelist: do_action(element) if check(element): remove_element_from_listсм. этот вопрос о том, как удалить из списка, хотя похоже, что вы уже видели это удалить элементы из списка во время итерации
другой вариант-сделать это, если вы действительно хотите сохранить это же
newlist = [] for element in somelist: do_action(element) if not check(element): newlst.append(element)
Не совсем на месте, но некоторые идеи, чтобы сделать это:
a = ['a', 'b'] def inplace(a): c = [] while len(a) > 0: e = a.pop(0) if e == 'b': c.append(e) a.extend(c)вы можете расширить функцию, чтобы вызвать фильтр в условии.
Comments