Python Forum
.remove() from a list - request for explanation
Thread Rating:
  • 0 Vote(s) - 0 Average
  • 1
  • 2
  • 3
  • 4
  • 5
.remove() from a list - request for explanation
#1
Hi guys,

I am learning python and I came across a weird thing which is hard for me to find the cause of it.
Here is my code:
l = [1, 2, 3, 2, 2, 2, 1]
for el in l:
  print("element: ", el)
  if el == 2:
    l.remove(el)
    print("list after removing el == 2: ", l)
  print("list for the next iteration: ", l)
Seriously, I don't know why the last number 2 is not taken into consideration to the next iteration of for-loop. Could anyone know the reason and may brighten up my mind, please?

[EDIT]
I added some comments to be printed and my idea is that after each iteration in which an element was removed, the length of the list is shorten, but the number of iteration is increasing and finally we have the length of a list equals 4 and the number of iteration is 4, so we cannot make any further iteration. Am I right? How could we fix that problem, does anybody have an idea?
l = [1, 2, 3, 2, 2, 2, 1]
for el in l:
  print('len list at the beginning of a new iteration: ', len(l))
  print("element: ", el)
  if el == 2:
    l.remove(el)
    print("list after removing el == 2: ", l)
    print('len list strict after removing el == 2: ', len(l))
  print("list for the next iteration: ", l)
  print('len list at the end of an iteration: ', len(l))
Reply
#2
It's a know bad pattern to remove element in a list/collection while iterate over it.
Will mess up list index and will get your result.
There is a easy fix if add l[:]: then iterate over a copy,
but it's slow as remove() has to go over the whole list for every iteration O(n^2).

So a couple of ways.
l = [1, 2, 3, 2, 2, 2, 1]
result = []
for el in l:
    if el != 2:
        result.append(el)
print(result) 
Output:
[1, 3, 1]
The same with list comprehension.
>>> l = [1, 2, 3, 2, 2, 2, 1]
>>> [el for el in l if el != 2]
[1, 3, 1]
InputOutput007 likes this post
Reply
#3
Don't modify an iterator while you're iterating over it. Some options are to loop over a copy of the list or to just copy the data you do want rather than delete the data you don't.

l = [1, 2, 3, 2, 2, 2, 1]
    for el in l[:]:  # loops over a copy of l.  Modifying l doesn't change the loop iterator.
    ...
l = [1, 2, 3, 2, 2, 2, 1]
l = [e for e in if l != 2]  # list comprehension copies the data we want directly
InputOutput007 likes this post
Reply
#4
@snippsat, @bowlofred - thank you for explanation
Reply


Possibly Related Threads…
Thread Author Replies Views Last Post
  Operator meaning explanation Sherine 3 103 Jul-31-2021, 11:05 AM
Last Post: Sherine
  Explanation of except ... as : Fernando_7obink 2 452 Feb-13-2021, 04:45 AM
Last Post: deanhystad
  .maketrans() - a piece of code which needs some explanation InputOutput007 5 536 Jan-28-2021, 05:05 PM
Last Post: buran
  Remove double quotes from the list ? PythonDev 22 2,302 Nov-05-2020, 04:53 PM
Last Post: snippsat
  Remove specific elements from list with a pattern Xalagy 3 787 Oct-11-2020, 07:18 AM
Last Post: Xalagy
  How to remove dict from a list? Denial 7 807 Sep-28-2020, 02:40 PM
Last Post: perfringo
  Explanation of the left side of this statement please rascalsailor 3 813 Sep-09-2020, 02:02 PM
Last Post: rascalsailor
  ImportError: cannot import name 'Request' from 'request' abhishek81py 1 1,503 Jun-18-2020, 08:07 AM
Last Post: buran
  Need explanation of one line of code Fliberty 6 1,086 Feb-18-2020, 12:50 AM
Last Post: Fliberty
  Remove all \n from end of list items JackMack118 4 29,013 Dec-27-2019, 08:34 AM
Last Post: perfringo

Forum Jump:

User Panel Messages

Announcements
Announcement #1 8/1/2020
Announcement #2 8/2/2020
Announcement #3 8/6/2020