Purify function not working


#1



https://www.codecademy.com/courses/python-intermediate-en-rCQKw/2/2?curriculum_id=4f89dab3d788890003000096#

I added some debug statements to my code. I am copying x into y to begin with because if I just use x and use the remove on that it skips the second 5 in the list. But it is still doing this even though I am looping through x while editing y. It appears to edit y as well as x which I don't understand.


I get "Oops, try again. Your function fails on purify([4, 5, 5, 4]). It returns [4, 5, 4] when it should return [4, 4]." My code removes objects from my list "x"

It should only remove objects from my list y. I believe my code should do what it is supposed to do.


def purify(x):
    y = x
    for n in x:
        print n
        print n % 2
        if n % 2 != 0:
            print y
            y.remove(n)
            print y
            print x
    return y
    
print purify([4,5,5,4])


#2

Hi @xflatx ,

Modifying the size of the list by removing items as you iterate through it causes problems. It messes up the iteration process by changing the positions of items in the list. So instead of doing this ...

y.remove(n)

... start with a new empty list. In the loop, append any even numbers that you find to the new list. After the loop, return the new list.


#3

Thanks, I will try this. However I still don't understand why items get removed from the x list if my statement has only y.remove(n). It seems like the x list should not be touched at all but it gets modified just the same way like the y list. Why is that?


#4

Using append on an empty list as you suggested works, thanks again for that.

I still don't understand why the remove doesn't work. Why is the iteration process messing up the positions?

And like I stated above why does the x list get modified when using y.remove(n)?

Thanks!


#5

Hi, @xflatx ,

This statement ...

y = x

... does not assign a copy of the list referenced by x to the variable y. It actually makes y refer to the same list as x. So if you change the list referred to by y, you are also changing the list referred to by x.

When you iterate through the items in a list with a for loop, the interpreter moves through the positions in the list sequentially. So, if you remove, say, the third item in the list while iterating through it, the fourth item then becomes the third item. But since the interpreter has just accessed the position of the third item, it then moves on to the position of the fourth item. However, due to the removal, the item that was the fourth item is now the third item, and the iteration misses the opportunity to access it.

To make a copy of the list referenced by x and assign that copy to y, you can do this ...

y = list(x)

... or this ...

y = x[:]

#6

Awesome! Thank you so much for that explanation! Now it makes all sense again :slight_smile: