views:

264

answers:

5

can someone please explain this to me??? this doesn't make any sense to me.... I copy a dictionary into another and edit the second and both are changed????

ActivePython 3.1.0.1 (ActiveState Software Inc.) based on
Python 3.1 (r31:73572, Jun 28 2009, 19:55:39) [MSC v.1500 32 bit (Intel)] on win32
Type "help", "copyright", "credits" or "license" for more information.
>>> dict1 = {"key1":"value1", "key2":"value2"}
>>> dict2 = dict1
>>> dict2
{'key2': 'value2', 'key1': 'value1'}
>>> dict2["key2"] = "WHY?!?!?!!?!?!?!"
>>> dict1
{'key2': 'WHY?!?!?!!?!?!?!', 'key1': 'value1'}
>>>
+7  A: 

Python never implicitly copies objects. When you set dict2 = dict1, you are making them refer to the same exact dict object, so when you mutate it, all references to it keep referring to the object in its current state.

If you want to copy the dict (which is rare), you have to do so explicitly with

dict2 = dict(dict1)

or

dict2 = dict1.copy()
Mike Graham
It might be better to say "dict2 and dict1 point to the **same** dictionary", you are not changing dict1 or dict2 but what they point to.
GrayWizardx
@GrayWizardx, I am not sure what you are suggesting. You think I should use the term "dictionary" instead of "dict object"?
Mike Graham
No I was saying that its a pointer thing, but then I tried to rewrite it without sounding like a curmudgeony old C++ programmer telling people that new languages suck. Its a common problem for people learning c++ as well. Your answer is perfect as is, and I already +1'ed it.
GrayWizardx
Also note that the dict.copy() is shallow, if there is a nested list/etc in there changes will be applied to both. IIRC. Deepcopy will avoid that.
Will
+1  A: 

dict2 = dict1 does not copy the dictionary. It simply gives you the programmer a second way (dict2) to refer to the same dictionary.

Paul Hankin
+3  A: 

When you assign dict2 = dict1, you are not making a copy of dict1, it results in dict2 being just another name for dict1.

To copy the mutable types like dictionaries, use copy / deepcopy of the copy module.

import copy

dict2 = copy.deepcopy(dict1)
Imran
A: 

Every variable in python (stuff like dict1 or str or __builtins__ is a pointer to some hidden platonic "object" inside the machine.

If you set dict1 = dict2,you just point dict1 to the same object (or memory location, or whatever analogy you like) as dict2. Now, the object referenced by dict1 is the same object referenced by dict2.

You can check: dict1 is dict2 should be True. Also, id(dict1) should be the same as id(dict2).

You want dict1 = copy(dict2), or dict1 = deepcopy(dict2).

The difference between copy and deepcopy? deepcopy will make sure that the elements of dict2 (did you point it at a list?) are also copies.

I don't use deepcopy much - it's usually poor practice to write code that needs it (in my opinion).

wisty
A: 

This confused me too, initially, because I was coming from a C background.

In C, a variable is a location in memory with a defined type. Assigning to a variable copies the data into the variable's memory location.

But in Python, variables act more like pointers to objects. So assigning one variable to another doesn't make a copy, it just makes that variable name point to the same object.

Craig McQueen
python variables act more like c++ references
wiso