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!

Thanks for your help


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