Apc
Apc

Reputation: 25

Using for loop in Python 3.4 to remove particular element from array

As I am new to programming in Python. I am trying to remove particular elements from array using for loop which looks like

a=[2,3,1,4,1,1,1,5]
n=a.count(1)
for i in range (len(a)-n):
    if (a[i]==1):
        del a[i]
    else:
        a[i]=a[i]
print (a)

I want to remove 1 from array a. But, I am getting result as:

[2, 3, 4, 1, 1, 5]. 

That is 1 still exists in my new array. Can somebody please answer my problem?

Upvotes: 1

Views: 1032

Answers (6)

Kasravnd
Kasravnd

Reputation: 107347

Actually as the del statement will remove elements from your list , and as the list that you bound in your loop doesn't been update after the first deleting you remove incorrect elements from your list , so if you want to use del you need to make the list name in your loop to reference to new list , that you can use a function for this aim , but as a more python way you can just use a list comprehension:

>>> a=[2,3,1,4,1,1,1,5]
>>> a=[i for i in a if i !=1]
>>> a
[2, 3, 4, 5]

Or you can use filter :

>>> a=[2,3,1,4,1,1,1,5]
>>> a=filter(lambda x: x !=1,a)
>>> a
[2, 3, 4, 5]

Upvotes: 0

Padraic Cunningham
Padraic Cunningham

Reputation: 180532

You can copy a and then remove but you cannot iterate over and delete elements from the same list, if your list starts with n elements python will have n pointers to each element so removing elements from the list as your are iterating over it will cause elements to be missed.python has no way of knowing you have removed elements from the list:

a = [2,3,1,4,1,1,1,5]
for ele in a[:]:
    if ele == 1:
        a.remove(1)
print(a)
[2, 3, 4, 5]

You can also use reversed which returns and iterator avoiding creating a whole copy of the list at once:

a = [2,3,1,4,1,1,1,5]
for  ele in reversed(a):
    if ele == 1:
        a.remove(1)
print(a)
[2, 3, 4, 5]

Or using a list comprehension with the [:] syntax so we actually update the original object:

a[:] = (ele for ele in a if ele != 1)

All the above are linear operations using a single pass over a.

Upvotes: 0

rbp
rbp

Reputation: 1898

The real answer to your question (which none of the other answers addresses) is that every time you remove an item, the index i moves past it.

in your case:

a = [2,3,1,4,1,1,1,5]

after deleting the 5th item in the original list, the pointer moves to the 6th item, and the new 5th item (the second 1 in the sequence of three 1s) is skipped.

Regarding the comment never modify a list in a loop, try to implement an in-place algorithm like Fisher-Yates without modifying the list. Never say never. Know what you're doing.

Upvotes: 2

Arcege
Arcege

Reputation: 438

The OP changes the list in-place, not creating a new list.

There are two methods, the second is safe, the first might be faster.

a = [2, 3, 1, 4, 1, 1, 1, 5]
toremove = 1
for i in range(len(a)-1, -1, -1):
    if a[i] == toremove:
        del a[i]

and

a = [2, 3, 1, 4, 1, 1, 1, 5]
toremove = 1
for i in range(a.count(toremove)):
    a.remove(toremove)

The second removes the element however many times it exists (before the loop). Since we are not iterating on the list, it is safe to use the remove method.

Both fragments should be O(n) (but haven't done the calculations).

Upvotes: 0

Malik Brahimi
Malik Brahimi

Reputation: 16721

Use a while loop and the remove method:

a = [2, 3, 1, 4, 1, 1, 1, 5]

while 1 in a:
    a.remove(1)

print a

Upvotes: 2

Hackaholic
Hackaholic

Reputation: 19763

try like this:

a = [2,3,1,4,1,1,1,5]
a = [x for x in a if x!=1]  # this is called list comprehension

note Never modify list while iterating

Upvotes: 3

Related Questions