How to create copies of a python object that are not linked to original object?

dictionary, object, python

Solution

The simplest way to make a shallow copy of a dictionary is to use the dict's `copy` method:

In [1]: template = {'thing1': '', 'thing2': '', 'thing3': ''}

In [2]: apile = template.copy()

In [3]: apile['thing1'] = 1

In [4]: apile
Out[4]: {'thing1': 1, 'thing2': '', 'thing3': ''}

In [5]: template
Out[5]: {'thing1': '', 'thing2': '', 'thing3': ''}

To make a shallow copy of a list, you can take a slice of the entire list:

copied_list = original_list[:]

If you need to clone other things, or if you need a deep copy of a dict of dicts (or a list of dicts, or other mutable objects), you should use the `copy` module: http://docs.python.org/2/library/copy.html

copy.copy(x)

Return a shallow copy of x.

copy.deepcopy(x)

Return a deep copy of x.

The difference between shallow and deep copying is only relevant for compound objects (objects that contain other objects, like lists or class instances):

- A shallow copy constructs a new compound object and then (to the extent possible) inserts references into it to the objects found in the original.

- A deep copy constructs a new compound object and then, recursively, inserts copies into it of the objects found in the original.

About your second way: sure, you can create a dict out of another dict, and it will be a copy:

In [23]: p = dict(template)

In [24]: p['thing1'] = 1

In [25]: template
Out[25]: {'thing1': '', 'thing2': '', 'thing3': ''}

In [26]: p
Out[26]: {'thing1': 1, 'thing2': '', 'thing3': ''}

Problem

(Using Python 2.7) I am trying to create replicates of a template object to be filled in later. For simplicity I tried to do it like this: ``` template={'thing1':'','thing2':'','thing3':''} for number in some_list: pile[number]=template ``` but later on when I did this: ``` pile[1]['thing1']='blahblah' ``` it also results in: ``` print pile[2]['thing1'] 'blahblah' print template['thing1'] 'blahblah' ``` What I want is for ``` pile[1]['thing1']='blahblah' ``` to leave pile[2] alone, so that ``` print pile[2]['thing1'] '' ``` And I know that the problem is that when I say ``` pile[number]=template ``` it means that pile[1] IS template, and pile[2] IS template. (This I only just fully realized today while working on this...and I repeated it to myself several times out loud as the realization and its implications slowly sank in... That's how python works, eh? I feel like I just joined the python club. I started out with MATLAB so don't be too rough on me.) So I imagine there might be two ways to go about this - one involves some kind of replication of objects that are not linked to the original, or something like that, and is probably really simple and obvious. And maybe there is another way to do it that is specific to dicts, like initializing the keys or something. I'm mostly interested in the first kind of answer, because that would help round out my understanding of how python works, but the second kind of answer would be nice too. Thanks :)

Original source