Python Python Collections Lists Removing items from a list

Stewart O'Neill
Stewart O'Neill
2,286 Points

Why am I being asked to move 1 to the front of the list, when line 4 of my code accomplishes this?

Why am I being asked to move 1 to the front of the list, when line 4 of my code accomplishes this?

lists.py
messy_list = ["a", 2, 3, 1, False, [1, 2, 3]]

# Your code goes below here
messy_list.insert(0, messy_list.pop(3))

for i in messy_list:
    if i != int:
        messy_list.remove(i)

1 Answer

Alex Koumparos
MOD
Alex Koumparos
Python Web Development Treehouse Moderator 32,441 Points

Hi Stewart,

You have a couple of issues with your code.

First, your comparison (if i != int) is not testing whether i is of type int, it is testing whether the concrete value i is equal to the int class. Since i will be an instance of a class, not the class itself, these will never be equal.

This is also why you have seen the specific error message you were getting: because the value 1 is not equal to the class int, 1 gets removed from the list. Since the challenge checker can't find 1 at the front of the list, it gives you that error message.

You can perform a type comparison using something like:

if isinstance(i, int):

However, it's worth remembering that Python is a duck-typed language and explicit type checking is generally considered an anti-pattern and should be avoided where possible.

In this challenge, it is possible to pass the task by explicitly removing the specified objects. Normally we wouldn't want to do this, but I suspect that Python's type system hasn't been taught yet in the course, so you wouldn't necessarily be expected to be able to work at the type level.

This would also get around your second issue, which probably also hasn't yet been taught. When you iterate through a mutable collection, you need to be very careful when doing something that might mutate the collection. What's happening with your for loop (assuming you fix the type comparison so that line behaves the way you intend) is this:

  • iteration 1: you are looking at the first element (1) of a six element list ([1, "a", 2, 3, False, [1, 2, 3]]). No changes;
  • iteration 2: you are looking at the second element ("a") of a six element list ([1, "a", 2, 3, False, [1, 2, 3]). We remove "a";
  • iteration 3: you are looking at the third element (3) of a five element list ([1, 2, 3, False, [1, 2, 3]). No changes;
  • iteration 4: you are looking at the fourth element (False) of a five element list ([2, 3, 1, False, [1, 2, 3]). We remove False;

There is no iteration 5 because at the end of iteration 4, the list is of length 4. Thus the last element [1, 2, 3] never gets considered (you'll also notice that 2 was never considered, but in this case we were lucky that we didn't want to do anything with 2).

Again, you would avoid this if you had just manually removed each item you didn't want in the list. This isn't a very satisfying approach. In the real world you might copy the list you are iterating through into a new list and then use remove on the copied list. Or you could start with an empty list and build up the new list with just the elements from the original list that you want to keep. Or you could use a list comprehension. All of these techniques are ones you will start learning soon.

Hope that clears things up for you.

Cheers

Alex

Stewart O'Neill
Stewart O'Neill
2,286 Points

Thank you for the explanation. It is now clear where I went wrong.

Best Stewart