Purify - Why removing doesn't work?


Hey guys, can anyone explain why the code below does not work (why it returns [4,5,4] instead of [4,4] when input is [4,5,5,4]) ?
(I'm not interested in the working solution as I already found it.)

def purify(lst):
    lst2 = lst
    for i in lst:
        if i % 2 == 1:
    return lst2


Because a list is a reference object it cannot be copied to another variable. It will not be a new list, just a reference to the old one. To make a copy that is not a reference, make a deep copy:

lst2 = lst[:]

Now lst2 is independent and you should be able to use .remove() on it.

>>> def purify(lst):
    lst2 = lst[:]
    for i in lst:
        if i % 2 == 1:
    return lst2

>>> purify([4,5,5,4])
[4, 4]


As far as I know a shallow copy is like a reference to the copied thing though, which makes the changes on one appear on the other too, making them dependant?


>>> lst1 = [4,5,5,4]
>>> purify(lst1)
[4, 4]
>>> lst1
[4, 5, 5, 4]

As we can see, lst1 is unaffected.


Then wouldn't it be wrong to call lst2 a shallow copy?


The result above would indicate there is nothing wrong. The copy is independent, with no bindings to the original list.

Shallow and deep copy operations

Yes, my mistake. It is a deep copy with no references to the first. Need to get my head out of the sand...


Here is one simpler example. No need to copy one list to another.

def purify(numbers):
new_list = []
for i in numbers:
if not(i % 2):
return new_list


The goal was to work with the OP's code and to resolve it, not come up with a simpler solution, which is moot, at this point. If all we want is simplicity then a list comprehension is hard to outdo.

def purify_list(n):
    return [i for i in n if not (i % 2)]


This topic was automatically closed 7 days after the last reply. New replies are no longer allowed.