Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Does Python make a copy of objects on assignment?

Tags:

python

I would expect that the following code would just initialise the dict_a, dict_b and dict_c dictionaries. But it seams to have a copy through effect:

dict_a = dict_b = dict_c = {} dict_c['hello'] = 'goodbye'  print dict_a print dict_b print dict_c 

As you can see the result is as follows:

{'hello': 'goodbye'} {'hello': 'goodbye'} {'hello': 'goodbye'} 

Why does that program give the previous result, When I would expect it to return:

{} {} {'hello': 'goodbye'} 
like image 722
Marcus Whybrow Avatar asked Mar 13 '10 15:03

Marcus Whybrow


People also ask

Does Python create a copy or reference?

5 Answers. Show activity on this post. Python always works by reference, unless you explicitly ask for a copy (a slice of a built-in list is deemed to "ask for a copy" -- but a slice of a numpy array also works by reference).

How are objects copied in Python?

In Python, we use = operator to create a copy of an object. You may think that this creates a new object; it doesn't. It only creates a new variable that shares the reference of the original object. Let's take an example where we create a list named old_list and pass an object reference to new_list using = operator.

Does assignment create a copy?

Assignment with an = on lists does not make a copy. Instead, assignment makes the two variables point to the one list in memory. So, if you edit the new list, changes will be reflected on the original list.

Does Python copy?

Assignment statements in Python do not create copies of objects, they only bind names to an object.


2 Answers

This is because in Python, variables (names) are just references to individual objects. When you assign dict_a = dict_b, you are really copying a memory address (or pointer, if you will) from dict_b to dict_a. There is still one instance of that dictionary.

To get the desired behavior, use either the dict.copy method, or use copy.deepcopy if your dict may have nested dicts or other nested objects.

>>> a = {1:2} >>> b = a.copy() >>> b {1: 2} >>> b[3] = 4 >>> a {1: 2} >>> b {1: 2, 3: 4} >>>  
like image 185
danben Avatar answered Oct 01 '22 02:10

danben


Even though

>>> dict_a, dict_b, dict_c = {}, {}, {} 

is the right way to go in most cases, when it get more than 3 it looks weird

Imagine

>>> a, b, c, d, e, f = {}, {}, {}, {}, {}, {} 

In cases where I wanna initialize more than 3 things, I use

>>> a, b, c, d, e, f, = [dict() for x in range(6)] 
like image 39
Jeffrey Jose Avatar answered Oct 01 '22 03:10

Jeffrey Jose