Welcome to the Treehouse Community

Want to collaborate on code errors? Have bugs you need feedback on? Looking for an extra set of eyes on your latest project? Get support with fellow developers, designers, and programmers of all backgrounds and skill levels here with the Treehouse Community! While you're at it, check out some resources Treehouse students have shared here.

Looking to learn something new?

Treehouse offers a seven day free trial for new students. Get access to thousands of hours of content and join thousands of Treehouse students and alumni in the community today.

Start your free trial

Python Python Collections (2016, retired 2019) Lists Removing items from a list

Ryan Francis
Ryan Francis
5,290 Points

Python Collections: Removing Items from a List Challenge Task 2

I decided to try to use a loop to solve this issue, but I encountered some strange behavior that I cannot explain. I created a for loop to go through the items in the list and used if to test the type() of the list item and if it != int, then it would remove it. This works until it gets to the list within the messy_list:

messy_list = ["a", 2, 3, 1, False, [1, 2, 3]]

# Your code goes below here
messy_list.insert(0, messy_list.pop(3))
for item in messy_list:
    if type(item) != int:
        del messy_list[messy_list.index(item)]

However, if I replace the del with a print(item), it will output the items that I would expect the loop to remove from the list:

messy_list = ["a", 2, 3, 1, False, [1, 2, 3]]

# Your code goes below here
messy_list.insert(0, messy_list.pop(3))
for item in messy_list:
    if type(item) != int:
        print(item)

What I find even more confusing, is if I keep the print and the del in, it will no longer print the list:

messy_list = ["a", 2, 3, 1, False, [1, 2, 3]]

# Your code goes below here
messy_list.insert(0, messy_list.pop(3))
for item in messy_list:
    if type(item) != int:
        print(item)
        del messy_list[messy_list.index(item)]

I am sure that there are far simply ways to solve this, but I'm really hung up on this because I can't explain why this happens. I have tested running the del manually and it works just fine.

>>> messy_list = ["a", 2, 3, 1, False, [1, 2, 3]]
>>> del messy_list[messy_list.index([1, 2, 3])]
>>> messy_list
['a', 2, 3, 1, False]
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 item in messy_list:
    if type(item) != int:
        print(item)

[MOD: added ```python formatting -cf]

1 Answer

Chris Freeman
MOD
Chris Freeman
Treehouse Moderator 68,441 Points

The primary issue is you should not modify the iterable of a for loop. Doing so affects the indexes and throws off the looping causing skipped items.

In the early-stage challenge, the purpose is to practice using various indexes on a list. It is OK to simply put integers as the index values. You do not need to search for items using index().

Using your third code attempt, It can pass the challenge if you make a copy of messy_list for the for loop. This way, the deletions do not alter the indexes of the copy.

messy_list = ["a", 2, 3, 1, False, [1, 2, 3]]

# Your code goes below here
messy_list.insert(0, messy_list.pop(3))
for item in messy_list.copy():  # <-- iterate over a copy of messy_list
    if type(item) != int:
        print(item)
        del messy_list[messy_list.index(item)]
Ryan Francis
Ryan Francis
5,290 Points

Thank you so much for your explanation! That makes complete sense.

That's what I wound up doing to pass the challenge, just passing the integers to list.remove() and not attempting to automate the process with a loop.

what is .copy( ) ?

Chris Freeman
Chris Freeman
Treehouse Moderator 68,441 Points

From the docs:

list.copy() Return a shallow copy of the list. Equivalent to a[:].

An example that uses most of the list methods:

>>>
>>> fruits = ['orange', 'apple', 'pear', 'banana', 'kiwi', 'apple', 'banana']
>>> fruits.count('apple')
2
>>> fruits.count('tangerine')
0
>>> fruits.index('banana')
3
>>> fruits.index('banana', 4)  # Find next banana starting a position 4
6
>>> fruits.reverse()
>>> fruits
['banana', 'apple', 'kiwi', 'banana', 'pear', 'apple', 'orange']
>>> fruits.append('grape')
>>> fruits
['banana', 'apple', 'kiwi', 'banana', 'pear', 'apple', 'orange', 'grape']
>>> fruits.sort()
>>> fruits
['apple', 'apple', 'banana', 'banana', 'grape', 'kiwi', 'orange', 'pear']
>>> fruits.pop()
'pear'