12/15 purify [code doesn't remove duplicated elements


#1

Hi,
my code for the purify practice looks like this:

def purify(lst):
    for i in lst:
        if i%2!=0:
            lst.remove(i)
    return lst

it return:

Oops, try again. Your function fails on purify([4, 5, 5, 4]). It returns [4, 5, 4] when it should return [4, 4].

What caused this problem? Thanks a lot!


#2

well, agree with me that if you have the list 4,5,5,4 that the items are indexed at 0,1,2 and 3? So, now python is going to loop over this values, at index 0, nothing has to be done (number is even), at index 1 we have to remove 5 since it is odd, now we continue to index 2, however, because we just delete a number, the second 5 (located index 2) has shifted to index 1. Meantime, we are at index 2, which now holds the value 4. OOPS.

Can you solve this problem? Yes, with a a try except IndexError and a while loop, which is getting pretty tricky. It is much easier to append even numbers to a new lists. Hope this helps, do ask if you have any questions


#3

Thanks very much! You've explained very well!


#4

Hi,

I tried to get over the problem you've described by creating a new list which the odd numbers will be removed from it, while the for loop will run on the original list:
def purify(lst):
list_var = lst
for i in lst:
if i%2!=0:
list_var.remove(i)
return list_var

but I still get the same error...
What's the problem? Thank you!


#5

The moral of the story is...

We should not .remove() inside a loop. Once we remove a value at an index position, any value above it falls down into that position. Only, if we advance to the next index position, we miss the one that just fell into the vacuum left by removal of the last one.

This is pretty tricky stuff, and easily avoided. It is still worthwhile exploring how it could be played out


#6

Mtf nails it. Don't do this. Just append your even numbers to a new list. This:

list_var = lst

will NOT create a new list.


#7

.remove() is a great incidental tool for when we know the index position or key name. Beyond that, it is not a tool we would want to build into any dynamic constructs. For that we would create incidental lists and go to work on them.

It goes without saying that any destructive operation starts at the END of the list, not the beginning. Thus determined iterability is preserved on the remaining.


#10

Delete is a horrible method, appending the items to a new list is a better idea.

Anyway, if you are to post code, explain what the code does. Just posting code is not according to the guidelines, thank you for your understanding