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

jessicamurr
jessicamurr
3,313 Points

Confusion with .copy() and .remove()

I'm having some trouble understanding why looping over a copy of a list doesn't have the same result as looping over the original list. There have been other questions similar to mine and great answers, but I am still having issues understanding.

Let's say:

letters = ["a", "b", "c", "d", "e"]
for letter in letters:
    letters.remove(letter)
    print(letters)
#output is ['b', 'd']

I get that the above is because when we start, the indexes are a = 0, b = 1, c = 2, d = 3, and e = 4 and then after we loop once, the indexes are shifted to b = 0, c = 1, d = 2, and e = 3, and so on and so forth each time we loop. And for every loop, the computer goes on to the next index to remove (loop 1 removes [0], loop 2 removes [1] - which is now c - and so on).

So, when we change the code to this

letters = ["a", "b", "c", "d", "e"]
letters_copy = letters.copy()
for letter in letters_copy:
    letters.remove(letter)
    print(letters)
#output is []

Why does this not do the same thing as above? We are looping over the copy of the letters, so doesn't the computer do the same thing: loop 1 removes [0], loop 2 removes [1], and so on to the original list since we are removing the letters from the original list? (After removing a, b is now [0], and since the loop is running again, why doesn't the computer move on to [1] since it just did [0] with the original list, therefore creating the same problem as before?)

Thank you in advance! Let me know if anything I asked is confusing!

1 Answer

Jennifer Nordell
seal-mask
STAFF
.a{fill-rule:evenodd;}techdegree
Jennifer Nordell
Treehouse Teacher

Hi there, jessicamurr ! The explanation is because you aren't removing from the thing you are iterating over. You're iterating over the copy and removing from the original. So the indexing of the copy isn't changing at all.

The copy looks like ["a", "b", "c", "d", "e"] and it will still look like that even after the loop has completed. If after the loop completes you were to print(letter_copy) you would see that it is still just as it was before the loop started. It's the original that will look different because that's the list you are removing from.

Alternatively, you could loop over the original and remove from the copy. The copy would then have the items removed and the original would remain the same. Ultimately, you need one version that remains constant and one that changes. The one you are iterating over should be the one that remains constant.

Hope this helps! :sparkles:

jessicamurr
jessicamurr
3,313 Points

THANK YOU! Your way of explaining somehow resonated more than the other explanations, so thank you for taking the time to answer. I get it now! :)