Code not working for purify task


#1



https://www.codecademy.com/courses/python-intermediate-en-rCQKw/2/2?curriculum_id=4f89dab3d788890003000096

I think of 2 options to do this task. however neither goes on well. For the first option, the error is "IndexError: list index out of range". For the second option, if I test a list a=[1,2,3,4,5,3,1], the result is [2, 4, 3]. Both 3 and 1 show 2 times in the original list, how come the purified list still has one 3 but no 1!!!! My best guess is that .remove(i) only remove the first value (i) in the list. But since this .remove(i) is in the loop, after the first "3" is removed, the second "3" will become the first "3" in the next round. Thus how come there is still 3 in the output. Any one can help point out the errors?


def purify(x):
    for i in range(0,len(x)):
        if x[i]%2==1:
            x.remove(x[i])

def purify(x):
    for i in x:
        if i%2==1:
            x.remove(i)


#2

lets say we have the following list:

[4,5,5,4]

the items at index 1 and index 2 need to be removed, right? But here is the problem, the moment you remove the 5 at index 1, the 5 of index 2 shifts to index 1, and the for loop continues to index, skipping double odd numbers.

Using the remove method is a bad idea for such problems, try appending the even numbers to a new list (create a new empty list first)


#3

A list is a mutable data type i.e. its elements can be changed. While looping through any sequence - list, set, dict, tuple etc it is assumed that the elements would not change. If you foresee any changes to the list, the best way to maintain data integrity is to create a copy and work on the copy while iterating through the original sequence.


#4

What @allentv is suggesting is the safest and surest approach so you don't mutate your original list, just return a purified one.

def purify(x):
    y = []
    for i in x:
        if i not in y:
            y.append(i)
    return y

While not necessarily applicable to this lesson (we need to learn how to write algorithms) Python has a built-in set() function that returns a list of unique values:

def no_duplicates(x):
    return [k for k in set(x)]

a = [4,5,6,5,4,3,4,5,6,7,8,7,9,4,5,6,7,8,9]

print no_duplicates(a)    # [3, 4, 5, 6, 7, 8, 9]

#5

A small improvement would be list(set(a))


#6

We were getting to that, but it still takes steps, and this step is important to see.