Чем del (item) отличается от list.remove (item) в списке Python

Я хотел удалить слова из списка длиной больше 3. Я использовал del (item), но это не сработало. Вот код:

lst=['XDA-OT','hi','loc','yeah']
for i in lst:
    if len(i)>3:
        del i

И вывод:

lst
['XDA-OT', 'hi', 'loc', 'yeah']

Теперь я использовал remove() из функций Python List и получил желаемый результат.

Вот код того же:

lst=['XDA-OT','hi','loc','yeah']
for i in lst:
    if len(i)>3:
        lst.remove(i)

ВЫХОД:

print(lst)
['hi', 'loc']

Также у меня есть сомнения относительно использования индекса списка для удаления элемента из списка, но я не понимал, как сформулировать вопрос.

Я получаю IndexError всякий раз, когда удаляю элемент с помощью index. КОД:

lst=['XDA-OT','hi','loc','yeah']
for i in range(len(lst)):
    if len(lst[i])>3:
        del lst[i]

ОШИБКА ВЫВОДА:

IndexError                                
<ipython-input-35-617282928840> in <module>()
      1 for i in range(len(lst)):
----> 2     if len(lst[i])>3:
      3         del lst[i]

IndexError: list index out of range

То же самое с функцией remove (). КОД:

lst=['XDA-OT','hi','loc','yeah']
for i in range(len(lst)):
    if len(lst[i])>3:
        lst.remove(lst[i])

ОШИБКА ВЫВОДА:

IndexError                                
<ipython-input-39-1d824ca5b061> in <module>()
      1 for i in range(len(lst)):
----> 2     if len(lst[i])>3:
      3         lst.remove(lst[i])

IndexError: list index out of range
del i просто удаляет переменную i. Это не влияет на ваш список.
khelwood 08.06.2018 12:00

Удалять элемент во время итерации - не лучший вариант. Вместо этого вы можете создать копию lst, используя .copy или срез [:], и перебрать и удалить, если из lst, если какое-то условие выполнено.

Abdul Niyas P M 08.06.2018 12:05

@abdul_niyas_pm, вы хотите сказать, сделать копию списка, перебрать оригинал и внести изменения в копию?

Abhay 08.06.2018 12:13
Почему в Python есть оператор "pass"?
Почему в Python есть оператор "pass"?
Оператор pass в Python - это простая концепция, которую могут быстро освоить даже новички без опыта программирования.
Некоторые методы, о которых вы не знали, что они существуют в Python
Некоторые методы, о которых вы не знали, что они существуют в Python
Python - самый известный и самый простой в изучении язык в наши дни. Имея широкий спектр применения в области машинного обучения, Data Science,...
Основы Python Часть I
Основы Python Часть I
Вы когда-нибудь задумывались, почему в программах на Python вы видите приведенный ниже код?
LeetCode - 1579. Удаление максимального числа ребер для сохранения полной проходимости графа
LeetCode - 1579. Удаление максимального числа ребер для сохранения полной проходимости графа
Алиса и Боб имеют неориентированный граф из n узлов и трех типов ребер:
Оптимизация кода с помощью тернарного оператора Python
Оптимизация кода с помощью тернарного оператора Python
И последнее, что мы хотели бы показать вам, прежде чем двигаться дальше, это
Советы по эффективной веб-разработке с помощью Python
Советы по эффективной веб-разработке с помощью Python
Как веб-разработчик, Python может стать мощным инструментом для создания эффективных и масштабируемых веб-приложений.
0
3
367
4
Перейти к ответу Данный вопрос помечен как решенный

Ответы 4

Как правило, я бы избегал изменения объекта, над которым выполняю итерацию. Это может привести к очень странному поведению.

Рассматривали ли вы решения с пониманием списка? Мне кажется, это самая питоническая реализация в данном случае.

lst = ['XDA-OT', 'hi', 'loc', 'yeah']
lst = [itm for itm in lst if len(itm) <= 3]

Понимание списка работает. Но, как вы объяснили для IndexError, если я использую range (len (lst) -1), я получаю желаемый результат. Почему здесь не возникла ошибка IndexError, поскольку здесь тоже удаляются элементы.

Abhay 08.06.2018 13:02

При использовании понимания списка новый список создается перед переназначением исходного списка. Таким образом, вам не нужно беспокоиться об индексировании. Вот небольшой пример, который вы можете проверить. Продвигайтесь вперед шаг за шагом и просмотрите используемые переменные: pythontutor.com/…

b3by 08.06.2018 14:23

У вас ошибка индекса, потому что вы изменяете список по ходу дела. Цикл for получает range(4), но в итоге lst[4] больше не существует, так как вы удалили некоторые элементы.

По поводу вопроса. del - это общая функция, которая удаляет объект, тогда как lst.remove() - это функция класса list. Итак, в вашем случае вы можете добиться того, чего хотите, используя оба.

Я бы порекомендовал вам использовать подход @ b3by, поскольку он использует понимание списка, которое в python быстрее, чем циклы for, как и вы.

Понимание списка работает. Но, как вы объяснили для IndexError, если я использую range (len (lst) -1), я получаю желаемый результат. Почему здесь не возникла ошибка IndexError, поскольку здесь тоже удаляются элементы.

Abhay 08.06.2018 13:06

@ user8810517 извините, но я не понимаю, что вы говорите

tupui 08.06.2018 13:25

Я имею в виду, что в моем коде, содержащем диапазон, я использовал диапазон (len (lst) -1) вместо диапазона (len (lst)), на этот раз я не получаю IndexError, и элементы удаляются. Как?

Abhay 08.06.2018 13:34

@ user8810517, потому что результатом является range(3), и он действителен до последнего вызова удаления. Но это не сработает, если ваш список как еще один элемент удалить. Также не забудьте принять ответ;)

tupui 08.06.2018 13:36

сэр, в ответ вы написали, что при удалении элемента последний индекс недействителен. Но в случае диапазона (len (lst) -1) элементы тоже удаляются, поэтому последний индекс не должен быть действительным. И я думаю, принимая ответ, вы имеете в виду проголосовать за него. Что ж, в этом случае я проголосовал за ответ, но поскольку моя репутация менее 15, он не будет показан публично.

Abhay 08.06.2018 14:11

@ user8810517 Позвольте перефразировать. Когда вы выполните цикл, i получит 0, 1, 2, 3. Когда i=0, он проверит lst[0], и тест скажет удалить, поэтому новый список будет ['hi', 'loc', 'yeah']. Итак, когда i=3 ищет lst[3], он больше не существует. При втором подходе у вас есть i, который является строкой, поэтому вы все еще можете выполнить удаление. Потому что i='yeah' и этот еще есть в списке. Принимая, я нажимаю на галочку, чтобы подтвердить, что ответ правильный. Это показывает всем, что ваша проблема решена :)

tupui 08.06.2018 14:18
Ответ принят как подходящий

del удаляет нужный элемент, где бы он ни находился.

Если используется в локальной переменной, он удалит локальную переменную, чтобы к ней нельзя было получить доступ снова, если она не будет воссоздана (то же самое применимо к области global)

То же самое с элементами list (del lst[2]) или элементами dict (del dct['MyKey'])


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

Если вы хотите удалить определенный элемент в list, вам не нужно хранить его в отдельной переменной:

 del lst[i]

Однако я бы рекомендовал пойти со вторым подходом и использовать list.remove (или list.pop, если на то пошло), поскольку он более явный и позволяет избежать нежелательных побочных эффектов.


Что касается вашего второго вопроса, вы получаете IndexError, потому что на каждой итерации вы уменьшаете размер списка (поскольку вы удаляете из него элементы), поэтому вы дойдете до точки, когда ваш i больше, чем длина список сам.

Понимание списка работает. Но, как вы объяснили для IndexError, если я использую range (len (lst) -1), я получаю желаемый результат. Почему здесь не возникла ошибка IndexError, поскольку здесь тоже удаляются элементы.

Abhay 08.06.2018 13:07

Это означает, что с помощью del (i) я удаляю объект «i», созданный на итерации по списку, а не элемент списка. Верно?

Abhay 08.06.2018 13:10

@ user8810517 Относительно вашего первого вопроса: это действительно зависит от списка и самих элементов, поэтому я бы не стал на это полагаться. Например, если вы попробуете использовать тот же список в другом порядке, например ['XDA-OT','hi','yeah', 'loc'], вы увидите, что использование range(len(lst)-1) на самом деле не работает.

Matias Cicero 08.06.2018 14:09

@ user8810517 Относительно второго вопроса: это правильно, вы просто удаляете переменную из области видимости. Он будет воссоздан на следующей итерации цикла, поэтому в основном выполнение del i ничего не дает. Однако вы можете увидеть описанное мной поведение, если попытаетесь получить к нему доступ до завершения цикла. Например, если вы добавите temp = i после del i, вы получите NameError, поскольку i был удален.

Matias Cicero 08.06.2018 14:11

С помощью оператора del вам нужно будет указать для индекса. Например

del list[0]

Простое удаление строкового значения из списка не будет работать с функцией del. Однако в этой ситуации будет работать метод .remove (). В качестве аргумента в .remove () просто передайте элемент списка, который вы хотите удалить из списка. Это может работать в цикле for следующим образом:

lst=['XDA-OT','hi','loc','yeah']
for i in lst:
   if len(i)>3:
      lst.remove(i)

print(lst)

И вот ваш результат:

['hi', 'loc']

Другие вопросы по теме