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 Object-Oriented Python Advanced Objects Subclassing Built-ins

Keith explanation for use of copy.copy

So Keith says he uses copy.copy because:

"Now why am I using copy.copy? Well, if they send in something mutable, like say, another list, each member in that filled list or each member in our filled list that was a copy of that list would be the same member if we weren't using copy.copy.

I follow until about here and then I don't understand this next part of the explanation

If you changed one of them it would change all of the others too because we're just putting in references to that list."

Would someone who understands what he is trying to say here be kind enough to explain it to me? I think he means that by using copy.copy each copy of a list object in our filled list would have a unique ID and if you tried to change a value in one of the lists that was appended it would only affect that specific instance.

Yep! You've got it!
Say you have a = [1, 2, 3] b = a

b only references a. So if you then said

b = [3, 2, 1] then a will also = [3, 2, 1]

But using copy.copy creates a NEW instance exactly the same as the original. So then you are working with two instances, and changes won't be propagated. And you will have:

a = [1, 2, 3] b = [3, 2, 1]

Chris Freeman
Chris Freeman
Treehouse Moderator 67,736 Points

Not precisely true:

>>> a = [1, 2, 3]
>>> b = a
>>> b = [3, 2, 1]
>>> a
[1, 2, 3]

Perhaps you meant:

>>> a = [1, 2, 3]
>>> b = a
>>> b[0] = 9
>>> a
[9, 2, 3]

3 Answers

Chris Freeman
MOD
Chris Freeman
Treehouse Moderator 67,736 Points

Good question! First two key concepts:

  • every object has a unique id value that represents its address in memory
  • a variable name, or label, is simply holds the value of an id
  • bonus: a list simply contains ids

Given that, arguments passed into a function are passed by their ids. The value argument holds the id of the object at value. Without using copy, the id of value would be appended repeatedly. By using copy.copy a new object is created, given a new id, then the new id is appended.

You can use the code below to see the ids of each item.

for item in container:
    print(id(item))

Using integers as an example doesn’t exhibit the same situation since integers are immutable. That is, copies of them will still point to the same object.

Using a list of lists is a better example:

>>> a = [[1], [2], [3]]
>>> for item in a:
...     print(id(item))
... 
5003754504
5000917768
5003625160
>>> b = []
>>> for item in a:
...     b.append(item)
... 
>>> for item in b:
...     print(id(item))
... 
5003754504
5000917768
5003625160
>>> import copy
>>> b = []
>>> for item in a:
...     b.append(copy.copy(item))
... 
>>> b
[[1], [2], [3]]
>>> for item in b:
...     print(id(item))
... 
5004452040
5004451976
5004453256
>>> 

Post back if you need more help. Good luck!!!

yes! thank you. I knew I was misfiring somewhere, but I wasn't registering. Thank you for correcting my oversight.

Ok, got it.Thank you both for the clarifying.