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
Trace Harris
Python Web Development Techdegree Graduate 22,065 Pointscompleted code challenge Though I am curious why a for loop with a if statement does not remove list within a list
messy_list = ["a", 2, 3, 1, False, [1, 2, 3]]
# int within list ascending order
messy_list.insert(0,messy_list.pop(3))
# remove all non interger within list
for item in messy_list:
if type(item) != int:
messy_list.remove(item)
else:
del messy_list[-1]
print(messy_list)
# results
[1, 2, 3, False, [1, 2, 3]]
[1, 2, 3 ] # correct solution
#this is where my question lies>
# remove all non interger within list
for item in messy_list:
if type(item) != int:
messy_list.remove(item)
print(messy_list)
#result
[1, 2, 3, False, [1, 2, 3]]
[1, 2, 3 , [1, 2, 3] ]
The first set of code satisfies the code challenge. For each item in messy_list i am checking weather or not the item is of the type <class 'int'> if item is not <class 'int'> I use the remove function. Else I delete the last item in the list. My question is this, If I do not use the else statement with the del function. In my for loop The loop fails to remove the last non integer item in the list, (See second set of results). My question is why? The type() function should return a <class 'list'> when it reaches that last list item in my messy_list which should satisfy the comparison and script should execute the removal, but it doesn't and I am not sure why.
2 Answers
Ryan S
27,276 PointsHi Trace,
Regarding your question on why the second for loop isn't working, it is because you are modifying the list (removing items) while you are iterating through it. Doing this will mess up the indexing of each item and you can end up skipping items. The reason the list within the list isn't caught by the type check is that you likely skipped over it due to the in-place modifications, and it was never actually processed.
The first for loop works, but only by accident. The combination of the index changes and the deletion of the last items in the list, which happen to be non-integers, just happens to work out. If you had a list with a different mix of items in a different order, then your loop would most likely not work.
To safely modify a list while you iterate through it, it is better to use a copy. I don't recall if slices have been introduced yet in this python course, but they can be used to create a quick copy of a list:
for item in messy_list[:]: # List slice (copy of messy_list)
if type(item) != int:
messy_list.remove(item) # Remove item from original messy_list
print(messy_list)
Hope this clears things up.
Alex Koumparos
Python Development Techdegree Student 36,888 PointsHi Trace,
I think the answer must be due to your indentation. I'm not sure how your code looked in the challenge, but it picked up some crazy indentation when it got copied and pasted into your question. When I copied and pasted your example code into my environment and then I fixed the indentation, I got the expected output (i.e., it did remove the list within the list).
Here is what the code looks like with just the indentation corrected:
messy_list = ["a", 2, 3, 1, False, [1, 2, 3]]
# int within list ascending order
messy_list.insert(0,messy_list.pop(3))
# remove all non interger within list
for item in messy_list:
if type(item) != int:
messy_list.remove(item)
else:
del messy_list[-1]
print(messy_list)
# results
[1, 2, 3, False, [1, 2, 3]]
[1, 2, 3 ] # correct solution
#this is where my question lies>
# remove all non interger within list
for item in messy_list:
if type(item) != int:
messy_list.remove(item)
print(messy_list)
#result
[1, 2, 3, False, [1, 2, 3]]
[1, 2, 3 , [1, 2, 3] ]
And here is the result from the interpreter:
[1, 2, 3]
Compare what I pasted to what your original code looked like before it got pasted into the question and mangled and that should reveal the problem.
Cheers
Alex
Trace Harris
Python Web Development Techdegree Graduate 22,065 PointsHi, Alex thanks for the answer. I don't believe it is an indentation based error. Just to double check I pasted the code with your formatting, into a text editor with indentation guides. still has the same behavior. I am wonder if the for loop is not reaching the last item? I have dropped a try and except statement. to see if I catch any ValueErrors or TypeErrors the code just Executes. I really do think this a language based behavior of Python and not do to any indentation or programmer errors, just trying to understand the behavior because I am curios. I want to know why!!!!!!!! also I,ll copy and paste your formatting into my question so it looks better no excuse for sloppiness.
Trace Harris
Python Web Development Techdegree Graduate 22,065 PointsTrace Harris
Python Web Development Techdegree Graduate 22,065 PointsThanks!!! I had my suspicions.. I knew I cheated using the first for loop, I knew the last item in messy_list was the list, I also knew that the first statement was leaving the list within messy_list through some debugging so I knew to catch it I would have to use an else statement with del messy_list[-1]. but yes using the slice is a more ideal approach, and no it has not been introduced yet but thanks. I really appreciate and this does clear things up for me and for that I am very grateful.