Why did updating the list that was added to the list change the list?

My code will be more clear, I think -

someList = list() foo = {'a':'b'} someList.append(foo) print someList >>> [{'a':'b'}] defaultbazz = {'a':2, 'b':'t', 'c':'gg'} for k, v in defaultbazz.iteritems(): foo[k] = v print someList >>> [{'a': 2, 'c': 'gg', 'b': 't'}] 

Should the last print be [{'a':'b'}] ? I have not updated someList , I want it as it is ..

It seems to me that this is an uninterpreted behavior.

But if it works like python, how can I find a workaround? Even installing a new dict updates the original dict. I mean:

 someList = list() foo = {'a':'b'} someList.append(foo) print someList >>> [{'a':'b'}] bar = foo defaultbazz = {'a':2, 'b':'t', 'c':'gg'} for k, v in defaultbazz.iteritems(): bar[k] = v print someList >>> [{'a': 2, 'c': 'gg', 'b': 't'}] 

I would be grateful if someone could explain to me why this is happening.

+4
source share
5 answers

It looks like you expect your dict to be copied when you add it to the list or assign it to a new variable, but that is not how Python works. If you assign a dict - in fact, if you assign an object - you do not create a new object, but instead you just give your object a new name. (An object can have multiple names.)

So, when you edit your object under a new name, one instance of this object changes, and this change is displayed when accessing the object through any name.

If you want to copy your object, you can do this:

 bar = dict(foo) 

or

 bar = foo.copy() 
+11
source

To simplify:

 a = {2: 3} b = [a] 

b contains a β€œlink” to a (and is a dict that is mutable) - therefore, if a changed, then access to a through list b display the changed a .

You must explicitly create a copy of a , which can be executed in this case as:

 b = [dict(a)] 

But you should look at the copy module for copy.copy() and copy.deepcopy()

+5
source

Dictionaries are mutable objects , so the result is your script. I assume you need a new object, i.e. copy of source:

 import copy someList.append(copy.copy(foo)) 
+3
source

Variables in Python are simply object names. If you change the object with any name attached to it, you will see the changes from any other name. Python never creates copies for you automatically, in particular:

 someList.append(foo) 

does not create a copy of foo and places it in someList , it adds an object to which the name foo refers.

You can create a middle name for this object.

 bar = foo 

but it also does not create a copy. In particular,

 foo['x'] = 42 

and

 bar['x'] = 42 

will work on exactly the same facility. You can verify this by typing the memory address of the object:

 print id(foo), id(bar) 

and make sure they are the same.

If you need a copy in Python, you will need to create it explicitly. Depending on what you need, the copy module - either copy.copy() or copy.deepcopy() - will do what you need:

 import copy bar = copy.copy(foo) print id(foo), id(bar) 

should now print different memory locations.

+2
source

Dictations are mutable, which means they can change. This is because foo is inside someList , and you change foo in the for-loop . Take a look at this simple example:

 a_dict = {'a':'b'} a_list = [a_dict] print a_list # [{'a':'b'}] #change the dict a_dict['a'] = 'c' print a_list # [{'a':'c'}] 
+1
source

All Articles