# Purify

#1

I can’t see why this doesn’t work (although I know the codecademy solution is the other way around) – surely this is also possible? What have I done wrong?:

def purify(numbers):

``````count = 0

for num in numbers:
if num % 2 != 0 or num == 1:
del(numbers[count])
count += 1

return numbers``````

#2

Hi @dannysaleeb,

The problem is that here you are altering the size of `numbers` as you iterate through it, which interferes with the iteration …

``````        del(numbers[count])
``````

Instead, create a new empty `list` and place each even number in that new `list`. Then, after the loop completes, `return` that new `list`.

Why have you included `or num == 1` in the `if` condition?

#3

Hi @appylpye – of course! Thanks for pointing this out, very helpful.

I also read somewhere that it’s generally bad practice to make destructive changes to the original list, so I understand the alternative solution is better – thank you. For argument’s sake, shouldn’t this get over the changing size of numbers, since the next num in numbers has the same index as the num removed (I get the same error still, but I feel it should work)?:

def purify(numbers):
count = 0
for num in numbers:
if num % 2 != 0:
del(numbers[count])
else:
count += 1
return numbers

Looks like I also didn’t need or num == 1 – I was thinking this might be needed since it’s less than 2, but that’s obviously not the case now that you’ve pointed it out!

#4

Consider this example …

``````print(purify([3, 7, 8]))
``````

The loop iterates through each position in the `list`. During the first iteration the `3` gets deleted because it is odd, the `7` gets shifted into the position at index `0`, and the `8` gets shifted to index `1`. The second iteration of the loop checks whatever is at index `1`, and the `7` that got shifted to index `0` gets overlooked and therefore remains in the `list`. At index `1`, we have `8`, which is even, so it does not get deleted. The result is `[7, 8]`, which is incorrect.

With some careful coding, you could work it out to get a correct result, but the necessary code would be more complicated than what you would need for creating a new `list` and placing each even number in that `list`.

#5

Cool – thanks very much – I get that. I thought maybe the following would get around the initial problem (careful as I am able!), by only altering the count if the number is even, but for some reason that wasn’t working either:

def purify(numbers):
count = 0
for num in numbers:
if num % 2 != 0:
del(numbers[count])
else:
count += 1
return numbers

This is just purely for curiosity though as I know now I should do it by creating a new list.

#6

PS: do you know the best way to quote code so that it comes out legible in the forum? (I did it somehow in my first post, but not sure how)

Thanks!

#7

The problem is that since this sets up an iteration the proceeds through each position, regardless of what you remove from the `list`

``````   for num in numbers:
``````

… the iteration will miss the second of two consecutive odd numbers, since removal of the first one causes a shift. To make sure the loop looks at each number, you could use `count` as an index for accessing the `list`, but you’d have to make sure that when `count` equals the current size of the `list`, you do not try to access an index that no longer exists for that shortened `list`. It gets a little messy.

Yes, check out Quick Tips for Writing Good Posts.

It is indeed important to format posted code so that the indentation is visible along with other details.

#8

Ah, I understand – thank you – very clear. Almost certainly not the last you’ll hear from me! Thanks again,

#9

Hint: You can do it using `del` within a `while` loop.

Replace the two comments with appropriate code …

``````def purify(numbers):
position = 0
while position < len(numbers):
if numbers[position] % 2 != 0:
# What should we do here?
else:
# What should we do here?
return numbers
``````

Important: Make sure you avoid an infinite loop.

Of course, the function alters the original `list`, while it is better to work with a new `list`.

#10

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