Я хотел удалить слова из списка длиной больше 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
Удалять элемент во время итерации - не лучший вариант. Вместо этого вы можете создать копию lst, используя .copy или срез [:], и перебрать и удалить, если из lst, если какое-то условие выполнено.
@abdul_niyas_pm, вы хотите сказать, сделать копию списка, перебрать оригинал и внести изменения в копию?






Как правило, я бы избегал изменения объекта, над которым выполняю итерацию. Это может привести к очень странному поведению.
Рассматривали ли вы решения с пониманием списка? Мне кажется, это самая питоническая реализация в данном случае.
lst = ['XDA-OT', 'hi', 'loc', 'yeah']
lst = [itm for itm in lst if len(itm) <= 3]
Понимание списка работает. Но, как вы объяснили для IndexError, если я использую range (len (lst) -1), я получаю желаемый результат. Почему здесь не возникла ошибка IndexError, поскольку здесь тоже удаляются элементы.
При использовании понимания списка новый список создается перед переназначением исходного списка. Таким образом, вам не нужно беспокоиться об индексировании. Вот небольшой пример, который вы можете проверить. Продвигайтесь вперед шаг за шагом и просмотрите используемые переменные: pythontutor.com/…
У вас ошибка индекса, потому что вы изменяете список по ходу дела. Цикл for получает range(4), но в итоге lst[4] больше не существует, так как вы удалили некоторые элементы.
По поводу вопроса. del - это общая функция, которая удаляет объект, тогда как lst.remove() - это функция класса list. Итак, в вашем случае вы можете добиться того, чего хотите, используя оба.
Я бы порекомендовал вам использовать подход @ b3by, поскольку он использует понимание списка, которое в python быстрее, чем циклы for, как и вы.
Понимание списка работает. Но, как вы объяснили для IndexError, если я использую range (len (lst) -1), я получаю желаемый результат. Почему здесь не возникла ошибка IndexError, поскольку здесь тоже удаляются элементы.
@ user8810517 извините, но я не понимаю, что вы говорите
Я имею в виду, что в моем коде, содержащем диапазон, я использовал диапазон (len (lst) -1) вместо диапазона (len (lst)), на этот раз я не получаю IndexError, и элементы удаляются. Как?
@ user8810517, потому что результатом является range(3), и он действителен до последнего вызова удаления. Но это не сработает, если ваш список как еще один элемент удалить. Также не забудьте принять ответ;)
сэр, в ответ вы написали, что при удалении элемента последний индекс недействителен. Но в случае диапазона (len (lst) -1) элементы тоже удаляются, поэтому последний индекс не должен быть действительным. И я думаю, принимая ответ, вы имеете в виду проголосовать за него. Что ж, в этом случае я проголосовал за ответ, но поскольку моя репутация менее 15, он не будет показан публично.
@ user8810517 Позвольте перефразировать. Когда вы выполните цикл, i получит 0, 1, 2, 3. Когда i=0, он проверит lst[0], и тест скажет удалить, поэтому новый список будет ['hi', 'loc', 'yeah']. Итак, когда i=3 ищет lst[3], он больше не существует. При втором подходе у вас есть i, который является строкой, поэтому вы все еще можете выполнить удаление. Потому что i='yeah' и этот еще есть в списке. Принимая, я нажимаю на галочку, чтобы подтвердить, что ответ правильный. Это показывает всем, что ваша проблема решена :)
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, поскольку здесь тоже удаляются элементы.
Это означает, что с помощью del (i) я удаляю объект «i», созданный на итерации по списку, а не элемент списка. Верно?
@ user8810517 Относительно вашего первого вопроса: это действительно зависит от списка и самих элементов, поэтому я бы не стал на это полагаться. Например, если вы попробуете использовать тот же список в другом порядке, например ['XDA-OT','hi','yeah', 'loc'], вы увидите, что использование range(len(lst)-1) на самом деле не работает.
@ user8810517 Относительно второго вопроса: это правильно, вы просто удаляете переменную из области видимости. Он будет воссоздан на следующей итерации цикла, поэтому в основном выполнение del i ничего не дает. Однако вы можете увидеть описанное мной поведение, если попытаетесь получить к нему доступ до завершения цикла. Например, если вы добавите temp = i после del i, вы получите NameError, поскольку i был удален.
С помощью оператора 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']
del iпросто удаляет переменнуюi. Это не влияет на ваш список.