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