By MadSc13ntist


2010-03-17 21:07:06 8 Comments

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. Why is this happening?

>>> dict1 = {"key1": "value1", "key2": "value2"}
>>> dict2 = dict1
>>> dict2
{'key2': 'value2', 'key1': 'value1'}
>>> dict2["key2"] = "WHY?!"
>>> dict1
{'key2': 'WHY?!', 'key1': 'value1'}

18 comments

@d4rty 2018-11-21 13:46:42

In addition to the other provided solutions, you can use ** to integrate the dictionary into an empty dictionary, e.g.,

shallow_copy_of_other_dict = {**other_dict}.

Now you will have a "shallow" copy of other_dict.

Applied to your example:

>>> dict1 = {"key1": "value1", "key2": "value2"}
>>> dict2 = {**dict1}
>>> dict2
{'key1': 'value1', 'key2': 'value2'}
>>> dict2["key2"] = "WHY?!"
>>> dict1
{'key1': 'value1', 'key2': 'value2'}
>>>

Pointer: Difference between shallow and deep copys

@sytech 2018-11-23 23:47:44

This results in a shallow copy, not a deep copy.

@d4rty 2018-11-24 07:48:54

@sytech Thank you for the advise, I revised my answer.

@ThatGuyRob 2018-12-13 18:25:30

I was trying this but having trouble. This only works for python 3.5 and up. python.org/dev/peps/pep-0448

@imcaozi 2018-09-30 14:59:25

>>> dict2 = dict1
# dict2 is bind to the same Dict object which binds to dict1, so if you modify dict2, you will modify the dict1

There are many ways to copy Dict object, I simply use

dict_1 = {
           'a':1,
           'b':2
         }
dict_2 = {}
dict_2.update(dict_1)

@Jean-François Fabre 2019-01-02 14:40:52

dict_2 = dict_1.copy() is much more efficient and logical.

@Emrit 2018-05-21 10:14:42

The best and the easiest ways to create a copy of a dict in both Python 2.7 and 3 are...

To create a copy of simple(single-level) dictionary:

1. Using dict() method, instead of generating a reference that points to the existing dict.

my_dict1 = dict()
my_dict1["message"] = "Hello Python"
print(my_dict1)  # {'message':'Hello Python'}

my_dict2 = dict(my_dict1)
print(my_dict2)  # {'message':'Hello Python'}

# Made changes in my_dict1 
my_dict1["name"] = "Emrit"
print(my_dict1)  # {'message':'Hello Python', 'name' : 'Emrit'}
print(my_dict2)  # {'message':'Hello Python'}

2. Using the built-in update() method of python dictionary.

my_dict2 = dict()
my_dict2.update(my_dict1)
print(my_dict2)  # {'message':'Hello Python'}

# Made changes in my_dict1 
my_dict1["name"] = "Emrit"
print(my_dict1)  # {'message':'Hello Python', 'name' : 'Emrit'}
print(my_dict2)  # {'message':'Hello Python'}

To create a copy of nested or complex dictionary:

Use the built-in copy module, which provides a generic shallow and deep copy operations. This module is present in both Python 2.7 and 3.*

import copy

my_dict2 = copy.deepcopy(my_dict1)

@shmuels 2018-07-10 15:13:27

I believe dict() creates a shallow copy not a deep copy. Meaning that if you have a nested dict then the outer dict will be a copy but the inner dict will be a reference to the original inner dict.

@Emrit 2018-07-16 14:12:08

@shmuels yes, both of these methods will create a shallow copy, not the deep one. See, the updated answer.

@PabTorre 2017-09-12 15:39:55

On python 3.5+ there is an easier way to achieve a shallow copy by using the ** unpackaging operator. Defined by Pep 448.

>>>dict1 = {"key1": "value1", "key2": "value2"}
>>>dict2 = {**dict1}
>>>print(dict2)
{'key1': 'value1', 'key2': 'value2'}
>>>dict2["key2"] = "WHY?!"
>>>print(dict1)
{'key1': 'value1', 'key2': 'value2'}
>>>print(dict2)
{'key1': 'value1', 'key2': 'WHY?!'}

** unpackages the dictionary into a new dictionary that is then assigned to dict2.

We can also confirm that each dictionary has a distinct id.

>>>id(dict1)
 178192816

>>>id(dict2)
 178192600

If a deep copy is needed then copy.deepcopy() is still the way to go.

@Ernesto 2017-09-12 17:00:11

This looks awfully like pointers in C++. Nice for accomplishing the task, but readability wise I tend to dislike this type of operators.

@PabTorre 2017-09-12 17:17:42

It does have a kind of c'ish look... but when merging together multiple dictionaries, the syntax does look pretty smooth.

@Sebastian Dressler 2018-01-29 11:17:56

Be careful with that, it performs only a shallow copy.

@PabTorre 2018-01-29 14:06:06

you are right @SebastianDressler, i'll makde adjustments. thnx.

@evg656e 2018-09-21 23:33:18

Usefull if you want create copy with some spicies: dict2 = {**dict1, 'key3':'value3'}

@PabTorre 2018-09-21 23:34:35

@evg656e very true. Although out of the scope for this particular question.

@personal_cloud 2017-09-16 23:09:13

As others have explained, the built-in dict does not do what you want. But in Python2 (and probably 3 too) you can easily create a ValueDict class that copies with = so you can be sure that the original will not change.

class ValueDict(dict):

    def __ilshift__(self, args):
        result = ValueDict(self)
        if isinstance(args, dict):
            dict.update(result, args)
        else:
            dict.__setitem__(result, *args)
        return result # Pythonic LVALUE modification

    def __irshift__(self, args):
        result = ValueDict(self)
        dict.__delitem__(result, args)
        return result # Pythonic LVALUE modification

    def __setitem__(self, k, v):
        raise AttributeError, \
            "Use \"value_dict<<='%s', ...\" instead of \"d[%s] = ...\"" % (k,k)

    def __delitem__(self, k):
        raise AttributeError, \
            "Use \"value_dict>>='%s'\" instead of \"del d[%s]" % (k,k)

    def update(self, d2):
        raise AttributeError, \
            "Use \"value_dict<<=dict2\" instead of \"value_dict.update(dict2)\""


# test
d = ValueDict()

d <<='apples', 5
d <<='pears', 8
print "d =", d

e = d
e <<='bananas', 1
print "e =", e
print "d =", d

d >>='pears'
print "d =", d
d <<={'blueberries': 2, 'watermelons': 315}
print "d =", d
print "e =", e
print "e['bananas'] =", e['bananas']


# result
d = {'apples': 5, 'pears': 8}
e = {'apples': 5, 'pears': 8, 'bananas': 1}
d = {'apples': 5, 'pears': 8}
d = {'apples': 5}
d = {'watermelons': 315, 'blueberries': 2, 'apples': 5}
e = {'apples': 5, 'pears': 8, 'bananas': 1}
e['bananas'] = 1

# e[0]=3
# would give:
# AttributeError: Use "value_dict<<='0', ..." instead of "d[0] = ..."

Please refer to the lvalue modification pattern discussed here: Python 2.7 - clean syntax for lvalue modification. The key observation is that str and int behave as values in Python (even though they're actually immutable objects under the hood). While you're observing that, please also observe that nothing is magically special about str or int. dict can be used in much the same ways, and I can think of many cases where ValueDict makes sense.

@Viiik 2017-08-02 10:21:08

You can use directly:

dict2 = eval(repr(dict1))

where object dict2 is an independent copy of dict1, so you can modify dict2 without affecting dict1.

This works for any kind of object.

@Eldritch Cheese 2017-10-31 17:11:18

This answer is incorrect, and should not be used. A user-defined class, for example, may not have an appropriate __repr__ to be reconstructed by eval, nor may the object's class be in the current scope to be called. Even sticking with built-in types, this will fail if the same object is stored under multiple keys, as dict2 would then have two separate objects. A self-referential dictionary, where dict1 contains itself, will instead contain Ellipsis. It would be better to use dict1.copy()

@Alexey 2018-02-21 12:50:23

Objects (or "values") are not expected to always have a faithful representation by character strings, not in a usual human readable way in any case.

@Vkreddy Komatireddy 2017-07-31 13:26:07

because, dict2 = dict1, dict2 holds the reference to dict1. Both dict1 and dict2 points to the same location in the memory. This is just a normal case while working with mutable objects in python. When you are working with mutable objects in python you must be careful as it is hard to debug. Such as the following example.

 my_users = {
        'ids':[1,2],
        'blocked_ids':[5,6,7]
 }
 ids = my_users.get('ids')
 ids.extend(my_users.get('blocked_ids')) #all_ids
 print ids#output:[1, 2, 5, 6, 7]
 print my_users #output:{'blocked_ids': [5, 6, 7], 'ids': [1, 2, 5, 6, 7]}

This example intention is to get all the user ids including blocked ids. That we got from ids variable but we also updated the value of my_users unintentionally. when you extended the ids with blocked_ids my_users got updated because ids refer to my_users.

@gpanda 2014-03-12 03:23:16

>>> x={'a': 1, 'b': {'m': 4, 'n': 5, 'o': 6}, 'c': 3}
>>> u=x.copy()
>>> v=dict(x)
>>> import copy
>>> w=copy.deepcopy(x)
>>> x['a']=10
>>> x
{'a': 10, 'c': 3, 'b': {'m': 4, 'o': 6, 'n': 5}}
>>> u
{'a': 1, 'c': 3, 'b': {'m': 4, 'o': 6, 'n': 5}}
>>> v
{'a': 1, 'c': 3, 'b': {'m': 4, 'o': 6, 'n': 5}}
>>> w
{'a': 1, 'c': 3, 'b': {'m': 4, 'o': 6, 'n': 5}}
>>> x['b']['m']=40
>>> x
{'a': 10, 'c': 3, 'b': {'m': 40, 'o': 6, 'n': 5}}
>>> u
{'a': 1, 'c': 3, 'b': {'m': 40, 'o': 6, 'n': 5}}
>>> v
{'a': 1, 'c': 3, 'b': {'m': 40, 'o': 6, 'n': 5}}
>>> w
{'a': 1, 'c': 3, 'b': {'m': 4, 'o': 6, 'n': 5}}

@Nikkolasg 2015-01-22 12:23:01

this should be the right answer as it doesn't to explicitly loop over the dict and can be used for other primary structures.

@alcoholiday 2015-09-23 14:06:02

Just to clarify: w=copy.deepcopy(x) is the key line.

@TheTank 2018-06-01 14:41:47

What is the difference between dict2 = dict1 and dict2 = copy.deepcopy(dict1) ?

@gpanda 2018-06-02 08:32:33

@TheTank, y=x makes the two names(references) refer to a same object, i.e. "y is x" is True. Any change made on the object through x is equivalent to a same change through y. However u, v, w are references to new different objects which have values copied from x during instantiation though. As for the differences between u,v(shallow copy) and w(deepcopy), please check docs.python.org/2/library/copy.html

@Petrus Theron 2016-12-23 16:58:05

dict1 is a symbol that references an underlying dictionary object. Assigning dict1 to dict2 merely assigns the same reference. Changing a key's value via the dict2 symbol changes the underlying object, which also affects dict1. This is confusing.

It is far easier to reason about immutable values than references, so make copies whenever possible:

person = {'name': 'Mary', 'age': 25}
one_year_later = {**person, 'age': 26}  # does not mutate person dict

This is syntactically the same as:

one_year_later = dict(person, age=26)

@Rodrigo Moraes 2016-12-22 23:14:09

Because python works with reference, so when you did dict2 = dict1 you pass a reference to dict2, that was the same as dict1. So, when you make a change in dict1 or dict2 you change a reference, and both dicts chages. Sorry if I mistake something on English.

@loosen 2016-12-10 12:25:25

Assignment statements in Python do not copy objects, they create bindings between a target and an object.

so, dict2 = dict1, it results another binding between dict2and the object that dict1 refer to.

if you want to copy a dict, you can use the copy module. The copy module has two interface:

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.

For example, in python 2.7.9:

>>> import copy
>>> a = [1,2,3,4,['a', 'b']]
>>> b = a
>>> c = copy.copy(a)
>>> d = copy.deepcopy(a)
>>> a.append(5)
>>> a[4].append('c')

and the result is:

>>> a
[1, 2, 3, 4, ['a', 'b', 'c'], 5]
>>> b
[1, 2, 3, 4, ['a', 'b', 'c'], 5]
>>> c
[1, 2, 3, 4, ['a', 'b', 'c']]
>>> d
[1, 2, 3, 4, ['a', 'b']]

@Frerich Raabe 2016-10-25 12:41:03

You can copy and edit the newly constructed copy in one go by calling the dict constructor with additional keyword arguments:

>>> dict1 = {"key1": "value1", "key2": "value2"}
>>> dict2 = dict(dict1, key2="WHY?!")
>>> dict1
{'key2': 'value2', 'key1': 'value1'}
>>> dict2
{'key2': 'WHY?!', 'key1': 'value1'}

@Dashing Adam Hughes 2014-03-06 03:28:22

You can also just make a new dictionary with a dictionary comprehension. This avoids importing copy.

dout = dict((k,v) for k,v in mydict.items())

Of course in python >= 2.7 you can do:

dout = {k:v for k,v in mydict.items()}

But for backwards compat., the top method is better.

@ApproachingDarknessFish 2015-01-26 05:43:46

This is particularly useful if you want more control over how and what exactly is copied. +1

@Jarek Piórkowski 2015-08-23 23:23:08

Note that this method does not perform a deep copy, and if you want a shallow copy with no need to control over keys to be copied, d2 = dict.copy(d1) doesn't require any imports either.

@Azat Ibrakov 2018-11-24 07:50:15

@JarekPiórkowski: or you can call a method like a method: d2 = d1.copy()

@Craig McQueen 2010-03-18 00:39:58

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.

@Ruggero Turra 2010-03-18 08:58:08

python variables act more like c++ references

@grimman 2013-11-23 12:24:48

Because everything in Python is an object! diveintopython.net/getting_to_know_python/… (yes, this response is many years late, but perhaps it's of some use to someone!)

@DevPlayer 2016-06-24 02:03:13

I believe that Python language semantics say there are no "variables". They are called "named references"; meaning the reference to an object is a syntactic string in code. An object can have many named references to it. Immutable objects like ints and floats and str instances have only one instance of it per process. An int of 1 in memory does not change to a 2 or some other value at the same memory address when you do this myvalue=1 myvalue=2

@wisty 2010-03-17 23:57:26

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).

@flutefreak7 2014-04-12 23:04:25

I just realized I need to always be using deepcopy so that when I copy a nested dictionary and start modifying nested entries, the effects occur only on the copy and not the original.

@Imran 2010-03-17 21:11:00

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)

@flutefreak7 2014-04-12 23:01:38

For any dictionary I ever work with, deepcopy is what I need... I just lost several hours due to a bug that was because I wasn't getting a complete copy of a nested dictionary and my changes to nested entries were affecting the original.

@fxstein 2015-02-10 03:05:02

Same here. deepcopy() does the trick. Was messing up my nested dicts inside a rotating cache by adding a timestamp to a 'copy' of the original event. Thank you!

@orezvani 2016-08-14 12:09:52

This actually should be marked as the correct answer; This answer is general and it works for a dictionary of dictionaries as well.

@Aaron John Sabu 2017-12-03 10:49:46

@orezvani, I agree with you. This is the only answer which satisfied my need.

@Cecil Curry 2017-12-05 03:44:39

This should be the accepted answer. The unsubstantiated "Deep copy is considered harmful" rhetoric embedded in the comment section of the current accepted answer blatantly invites synchronization woes when copying nested dictionaries (such as those documented here) and should be challenged as such.

@user97370 2010-03-17 21:09:44

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

@Mike Graham 2010-03-17 21:09:08

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()

@GrayWizardx 2010-03-17 21:15:33

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.

@Mike Graham 2010-03-17 21:17:45

@GrayWizardx, I am not sure what you are suggesting. You think I should use the term "dictionary" instead of "dict object"?

@GrayWizardx 2010-03-17 21:45:54

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.

@Will 2010-03-18 07:08:39

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.

@daniel kullmann 2012-03-06 10:34:44

It is not quite correct that python never implicitly copies objects. Primitive data types, such as int, float, and bool, are also treated as objects (just do a dir(1) to see that), but they are implicitly copied.

@Mike Graham 2012-03-06 15:03:09

@danielkullmann, I think you might have misunderstandings about Python based on how other languages you've dealt with work. In Python, a) There is no concept of "primitive data types". int, float, and bool instances are real Python objects, and b) objects of these types are not implicitly copied when you pass them, not at a semantic Python level for sure and not even as an implementation detail in CPython.

@Adam Rosenfield 2012-11-15 21:04:16

Another possibility: dict2 = copy.copy(dict1) (documentation)

@Mike Graham 2012-11-15 22:13:02

I recommend doing your best to forget the copy module exists.

@Joe 2013-01-12 23:51:01

Note that using dict1.copy() will ensure your resulting type is the same as dict1 when necessary. This may be important, e.g. when using OrderedDict

@Ben 2014-03-20 00:53:47

This answer should have been ticked as the correct answer.

@flutefreak7 2014-04-12 22:59:26

Use deepcopy if your dictionary is multiple layers deep and you want a completely independent copy... otherwise dcopy = d.copy(); dcopy['top']['nested']['bottom'] = 1 will change the object referred to by d['top']['nested']['bottom'] as well. This burned me when trying to apply a range of offsets for a batch analysis to a value in a data structure inside a loop... my offsets were acting cumulatively because they were affecting the original as well as the copy.

@Mike Graham 2014-04-13 18:42:45

Be very careful when you use copy.deepcopy -- it's very easy to introduce silent bugs. It can and should be avoided the vast majority of the time.

@user1938107 2014-10-07 07:15:06

@MikeGraham could you mention why you say it is 'rare' to copy a dict?

@Mike Graham 2014-10-11 15:26:11

@user1938107, More often you build a dict with the differences you want rather than copying the dict then mutating it.

@user1938107 2014-10-11 23:09:49

@MikeGraham i see. thanks for the clarification

@naught101 2015-09-10 00:34:38

@MikeGraham: Could you point to some examples of silent bugs from deepcopy? Something to do with sub-objects not copying properly?

@DiCaprio 2015-09-11 10:47:45

So if I want to call a function that is not allowed to change the dict, I'd like to call function(dict(myDict)). But now changes in function to the input still apply to myDict. Am I doing it wrong?

@orezvani 2016-08-14 12:06:53

What about a deep copy? What if I want to copy a dictionary of dictionaries? In that case, you would need dict2 = copy.deepcopy(dict1) from import copy

@Arco Bast 2016-08-24 14:04:45

@MikeGraham: Same question as naught101: what bugs might arise from using deepcopy?

@personal_cloud 2017-09-16 22:38:14

@MikeGraham: When you say more often you build a dict with the differences... So are you saying you use a dict that automatically links back to the original dict for fields that didn't change? Isn't it simpler to just copy the dict in such cases?

@user2357112 2017-09-16 23:44:24

@naught101: It's very easy to accidentally copy too deep - there's often a point at which you want to stop copying. The cyclic reference handling is also kind of ad hoc and not as reliable as the docs would have you believe. One not-so-silent example is what happens if you try to deepcopy a self-referential OrderedDict on Python 2.

@naught101 2017-09-18 01:57:35

@user2357112: haha... that looks like a well-deserved runtime error. I can't see how something like that would ever end well, or be a good idea to start with :P

@user2357112 2017-09-18 02:28:08

@naught101: The thing is, copy.deepcopy claims it doesn't have problems with reference loops.

@naught101 2017-09-19 04:01:12

@user2357112: that code actually works fine on python 3.6.1... Still seems like a bad idea.

@Kirill Bulygin 2017-10-02 17:35:35

@naught101 I would also recommend to avoid deep-copying, not to avoid implementation errors in a library but to avoid design error in your own code. Copying is an expensive operation, and editing in-place or storing changes is often much faster (unless you really need fast access to the history of your object, but even then full copying is not necessary, see Redux). Another reason is that by copying you lose the single truth of source: all copies need to be updated for changes, and this can easily go inconsistent. As a rule of thumb, copy only if you can't control the code you share data with.

@Cecil Curry 2017-12-05 03:39:13

Unsubstantiated rhetoric like "Deep copy is considered harmful" is unhelpful. All else being equal, shallow copying a complex data structure is significantly more likely to yield unexpected edge case issues than deep copying the same structure. A copy in which modifications modify the original object isn't a copy; it's a bug. Ergo, most use cases absolutely should call copy.deepcopy() rather than dict() or dict.copy(). Imran's concise answer is on the right side of sanity, unlike this answer.

@Martijn Pieters 2018-03-06 10:16:42

@CecilCurry: the proper answer is to understand how the Python object model works, of course. I recommend people read Ned Batchelder's article on Python names, so they can make their own informed decision on what kind of copying they need. Sometimes the answer is not to copy at all, or to use a loop with shallow copying.

@otayeby 2018-03-16 02:17:06

Both solutions didn't work for me, but deep.copy() worked

@shahar_m 2018-04-25 11:02:28

Usually you copy a dictionary in order to change it. In that case, both shallow copy methods fails, you need dict2 = copy.deepcopy(dict1).

Related Questions

Sponsored Content

21 Answered Questions

[SOLVED] Check if a given key already exists in a dictionary

  • 2009-10-21 19:05:09
  • Mohan Gulati
  • 2636038 View
  • 2515 Score
  • 21 Answer
  • Tags:   python dictionary

40 Answered Questions

[SOLVED] How do I check whether a file exists without exceptions?

14 Answered Questions

[SOLVED] Add new keys to a dictionary?

  • 2009-06-21 22:07:39
  • lfaraone
  • 2724005 View
  • 2133 Score
  • 14 Answer
  • Tags:   python dictionary

24 Answered Questions

[SOLVED] How do I pass a variable by reference?

44 Answered Questions

[SOLVED] How to merge two dictionaries in a single expression?

26 Answered Questions

[SOLVED] What is the best way to iterate over a dictionary?

  • 2008-09-26 18:20:06
  • Jake Stewart
  • 1286593 View
  • 2162 Score
  • 26 Answer
  • Tags:   c# dictionary loops

12 Answered Questions

[SOLVED] Iterating over dictionaries using 'for' loops

19 Answered Questions

[SOLVED] How to clone or copy a list?

18 Answered Questions

41 Answered Questions

[SOLVED] How do I sort a dictionary by value?

Sponsored Content