Welcome to the Treehouse Community

The Treehouse Community is a meeting place for developers, designers, and programmers of all backgrounds and skill levels to get support. Collaborate here on code errors or bugs that you need feedback on, or asking for an extra set of eyes on your latest project. Join thousands of Treehouse students and alumni in the community today. (Note: Only Treehouse students can comment or ask questions, but non-students are welcome to browse our conversations.)

Looking to learn something new?

Treehouse offers a seven day free trial for new students. Get access to thousands of hours of content and a supportive community. Start your free trial today.

Python Python Collections (Retired) Lists Redux Manipulating Lists

Timothy Bass
Timothy Bass
888 Points

Challenge Task 2 of 3 - works in workspace.... but sadly

So this works in the work space with an output of [1, 2, 3, [1, 2, 3]]

But not in the 'homework' part of it.

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

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

for item in the_list:
  if isinstance(item, str) or isinstance(item, bool):
    the_list.remove(item)

print(the_list)

1 Answer

Chris Freeman
MOD
Chris Freeman
Treehouse Moderator 68,106 Points

Kudos for taking taken a unique approach. Two aspects need fixing.

  • Also check for the type list
  • and it's almost never a good idea to manipulate the list you looping over as it causes index errors Use a copy instead:
the_list = ["a", 2, 3, 1, False, [1, 2, 3]]

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

for item in the_list[:]:  # <-- use [:] to signify a copy
  if isinstance(item, str) or isinstance(item, bool) or isinstance(item, list):  # <-- added 'list' check
    the_list.remove(item)

Also, the print(the_list) is unnecessary.

Others that have solved this challenged used a more brute force approach of:

the_list.remove(False)
the_list.remove("a")
the_list.remove([1, 2, 3])

Chris, could you please briefly explain why the code below doesn't remove the list ([1,2,3]) in case if a copy ([:]) is not created. Thanks.

for item in the_list[:]:  # <-- use [:] to signify a copy
  if isinstance(item, str) or isinstance(item, bool) or isinstance(item, list): 
Chris Freeman
Chris Freeman
Treehouse Moderator 68,106 Points

Expanding the code to add print statements and clarify the test case:

the_list = ["a", 2, 3, 4, 1, False, [1, 2, 3]]

# Your code goes below here
the_list.insert(0, (the_list.pop(4)))

for item in the_list[:]:  # <-- use [:] to signify a copy
  if isinstance(item, str) or isinstance(item, bool) or isinstance(item, list):  # <-- added 'list' check
    print('removing item ', item, ' from ', the_list)
    the_list.remove(item)

print('final list: ', the_list)

Results in:

removing item  a  from  [1, 'a', 2, 3, 4, False, [1, 2, 3]]
removing item  False  from  [1, 2, 3, 4, False, [1, 2, 3]]
removing item  [1, 2, 3]  from  [1, 2, 3, 4, [1, 2, 3]]
final list:  [1, 2, 3, 4]

Removing copy:

the_list = ["a", 2, 3, 4, 1, False, [1, 2, 3]]

# Your code goes below here
the_list.insert(0, (the_list.pop(4)))

for item in the_list:  # <-- removed [:] 
  if isinstance(item, str) or isinstance(item, bool) or isinstance(item, list):  # <-- added 'list' check
    print('removing item ', item, ' from ', the_list)
    the_list.remove(item)

print('final list: ', the_list)

Results in:

removing item  a  from  [1, 'a', 2, 3, 4, False, [1, 2, 3]]
removing item  False  from  [1, 2, 3, 4, False, [1, 2, 3]]
final list:  [1, 2, 3, 4, [1, 2, 3]]

The list [1, 2, 3] is not removed because the container iterated over by the for loop is shrinking as each item is removed.

In the loop, the next item from the iterable the_list is referenced by index: 0, 1, 2, 3, ....

Using [1, "a", 2, 3, 4, False, [1, 2, 3]]

  • First loop [0] is 1
  • Next loop [1] is "a" which is removed; 2 shifts to index [1]
  • Next loop [2] is 3
  • Next loop [3] is 4
  • Next loop [4] is False which is removed; [1, 2, 3] shifts to index [4]
  • Next loop exits because there is nothing at index [5].

The item [1, 2, 3] had shifted to index [4] due to the items removed effectively being skipped in the loop. Checking 2 was also skipped.

Thanks, Chris!