Purify - Why removing doesn't work?


#1


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:
            lst2.remove(i)
    return lst2


#2

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:
            lst2.remove(i)
    return lst2

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

#3

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?


#4

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

As we can see, lst1 is unaffected.


#5

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


#6

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...


#7

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):
new_list.append(i)
return new_list


#8

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)]

#9

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