-3

I want to remove the select element in sequence.

For example, I want to remove all 2 in sequence [1,2,3,2,3]

my code is

def remove_all(a_list, element):
    for i in range(len(a_list)):
        if element == a_list[i]:
            a_list.remove(element)
            return a_list

The output should be [1,3,3]

but the output of my code is [1,3,2,3]

I remove the first 2 but somehow the loop didn't go further to remove second 2. I wonder where is the problem of my code

rusttree
  • 19
  • 5
  • 4
    I don't think you want to `return a_list` until after the loop is complete. But you also don't want to modify the loop your iterating over while you're iterating over it. – Fred Larson Nov 04 '21 at 12:41
  • 3
    [Thou Shalt Not Modify A List During Iteration](https://unspecified.wordpress.com/2009/02/12/thou-shalt-not-modify-a-list-during-iteration/) – Jab Nov 04 '21 at 12:42
  • 1
    Does this answer your question? [Using for loop in Python 3.4 to remove particular element from array](https://stackoverflow.com/questions/28265097/using-for-loop-in-python-3-4-to-remove-particular-element-from-array) – Antoine Nov 04 '21 at 12:44
  • 2
    See also [Python list.remove() skips next element in list](https://stackoverflow.com/q/14267722/3890632) – khelwood Nov 04 '21 at 12:56

4 Answers4

2

Removing items in-place will almost certainly results in index errors.

[x for x in l if x != elem]
kgiannakakis
  • 103,016
  • 27
  • 158
  • 194
2

2 things.

  • You are modifying a list during iteration, I linked to a good read in my comment. also here
  • You return in the loop thus it stops at the return. Unindent the return, python is all about indentation unlike many other popular languages in this matter.

Try instead

  • Building another list for return:

    def remove_all(a_list, element):
        result = []
        for ele in a_list:
            if element != ele:
                result.append(ele)
        return result
    
  • Using a comprehension:

    def remove_all(a_list, element):
        return [ele for ele in a_list if ele != element]
    
Jab
  • 26,853
  • 21
  • 75
  • 114
  • you forgot to un-indent your first example, and have double returns in the second one – Mahrkeenerh Nov 04 '21 at 12:48
  • @Mahrkeenerh Thank you! formatting/pasting issue. – Jab Nov 04 '21 at 12:51
  • one thing about the second example is that there is a typo. The alist.copy() should be a_list.copy(). Also, I can't run that function. I am getting the following error: in remove_all del result[i] IndexError: list assignment index out of range – thecatbehindthemask Nov 05 '21 at 10:48
  • @thecatbehindthemask Thanks, I wrote that after I answered without running. I just removed it. – Jab Nov 05 '21 at 14:35
-1

a possible work-around is:

while element in a_list:
    a_list.remove(element)

return element

But list comprehension works too, possibly even faster.

Mahrkeenerh
  • 1,104
  • 1
  • 9
  • 25
-1

You should place the return after the loop finishes, something like:

def remove_all(a_list, element):
for i in a_list:
    if element == i:
        a_list.remove(element)
return a_list


a_list = [1, 2, 3, 2, 3]
result = remove_all(a_list, 2)

print(result)

Edit: The code above does not work with the [2,2] case as pointed out in the comments. Another solution would be:

myList = [2,2]
myList = list(filter((2).__ne__, myList))
print(myList)

Like that you don't copy the list anywhere, just is the list you are working on avoiding a list copy that can be expensive.

The __ne__ function checks that the element exists in the list returning True or False.

thecatbehindthemask
  • 413
  • 1
  • 6
  • 15