14

I think I'm starting to understand python, but I still have trouble with a basic question. When to use copy.copy?

>>>a=5
>>>b=a
>>>a=6
>>>print b
5

Ok makes sense. But in what circumstances does saying b=a form some kind of 'link' between a and b such that modifying a would then modify b? This is what I don't get about copy.copy -- does every time you assign one variable to another with the equals sign just copy the value?

agf
177k45 gold badges299 silver badges241 bronze badges
asked Aug 12, 2011 at 22:26
1
  • 3
    Assignment in Python never copies values. Commented Aug 13, 2011 at 0:51

2 Answers 2

34

Basically, b = a points b to wherever a points, and nothing else.

What you're asking about is mutable types. Numbers, strings, tuples, frozensets, booleans, None, are immutable. Lists, dictionaries, sets, bytearrays, are mutable.

If I make a mutable type, like a list:

>>> a = [1, 2] # create an object in memory that points to 1 and 2, and point a at it
>>> b = a # point b to wherever a points
>>> a[0] = 2 # change the object that a points to by pointing its first item at 2
>>> a
[2, 2]
>>> b
[2, 2]

They'll both still point to the same item.

I'll comment on your original code too:

>>>a=5 # '5' is interned, so it already exists, point a at it in memory
>>>b=a # point b to wherever a points
>>>a=6 # '6' already exists in memory, point a at it
>>>print b # b still points at 5 because you never moved it
5

You can always see where something points to in memory by doing id(something).

>>> id(5)
77519368
>>> a = 5
>>> id(a)
77519368 # the same as what id(5) showed us, 5 is interned
>>> b = a
>>> id(b)
77519368 # same again
>>> id(6)
77519356
>>> a = 6
>>> id(a)
77519356 # same as what id(6) showed us, 6 is interned
>>> id(b)
77519368 # still pointing at 5. 
>>> b
5

You use copy when you want to make a copy of a structure. However, it still will not make a copy of something that is interned . This includes integers less than 256, True, False, None, short strings like a. Basically, you should almost never use it unless you're sure you won't be messed up by interning.

Consider one more example, that shows even with mutable types, pointing one variable at something new still doesn't change the old variable:

>>> a = [1, 2]
>>> b = a
>>> a = a[:1] # copy the list a points to, starting with item 2, and point a at it
>>> b # b still points to the original list
[1, 2]
>>> a
[1]
>>> id(b)
79367984
>>> id(a)
80533904

Slicing a list (whenever you use a :) makes a copy.

answered Aug 12, 2011 at 22:39
1
  • Excellent answer. I always knew that immutable types were copied by value, not reference. Now I know why!
    wbg
    Commented Nov 2, 2011 at 23:26
4

Assignment never copies. It just links the object the a references (to stick to the example) to b. a and b reference the same object until you change the link of one.

It's useful to drop "variable" as a term, it's just a label you put on an object, a handle you can use to get through to the object, nothing more.

copy.copy doesn't change this at all.

If you want to propagate changes even for numbers or strings - here does the immutability show - you have to wrap the numbers and strings in a another object and assign it to a and b.

If you want to go the other way round you have to use the copy module, but make sure to read the docs. But you have to think in term of objects not variables.

answered Aug 12, 2011 at 22:38
1

Your Answer

Draft saved
Draft discarded

Sign up or log in

Sign up using Google
Sign up using Email and Password

Post as a guest

Required, but never shown

Post as a guest

Required, but never shown

By clicking "Post Your Answer", you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.