0
ddic = {'a': 10,'b': 23,'c': [0, 1, 2]}
n2 = ddic['c']
n2[-2] = 1000.

ddic
{'a': 10, 'b': 23, 'c': [0, 1000.0, 2]}

Why changing the list at which n2 is pointing, changes also the list of dict ddic, which is contained into the hash table that ddic defines?

It looks like that when you define a dict, the key-value pairs pops-in the global namespace and is not contained into the namespace defined by the hash-table structure.

Someone knows the detailed reason of this?

Bhargav Rao
  • 50,140
  • 28
  • 121
  • 140
  • Please [accept](http://meta.stackexchange.com/questions/5234) an answer if you think it solves your problem. It will community at large to recognize the correct solution. This can be done by clicking the green check mark next to the answer. See this [image](http://i.stack.imgur.com/uqJeW.png) for reference. Cheers. – Bhargav Rao Dec 09 '15 at 07:44

3 Answers3

2

Few prenotes

  • Dict keys are immutable whereas values are mutable.
  • When you use =, the new variable just references the old list

The value at key c is a list. It is pointed to by the key at that place. On copying to a variable, the reference is passed. This can be confirmed by using id.

>>> id(ddic['c'])
140726603094424
>>> id(n2)
140726603094424

As you see both the variables are pointing to the same element in memory. Hence any changes you make in one are reflected to the original one also.

To have a shallow copy of the list you can use [:] as mentioned by Blckknght

>>> n2 = ddic['c'][:]

In python3, you can use (as mentioned by Padraic)

>>> n2 = ddic['c'].copy()

Using copy module, you can prevent this from happening as in

>>> import copy
>>> n2 = copy.copy(ddic['c'])
>>> id(ddic['c'])
140726603094424
>>> id(n2)
140726603177640

Reference

Also note that as mentioned by Kasra in the comments, dicts don't have as separate space for them as they are data structures. You can find refernce in this document

Community
  • 1
  • 1
Bhargav Rao
  • 50,140
  • 28
  • 121
  • 140
1

This is a classic trap Python beginner fall into. Some object in Python are immutable (e.g. integer, string, tuple). Some object are mutable (e.g.: list, dictionary, instances).

If you modify a mutable object all other objects that reference that object will see the modified value.

if you don't want to modify ddic['c'] you have to make a copy

n2 = list(ddic['c'])
n2[-2] = 1000

ddic
{'a': 10,'b': 23,'c': [0, 1, 2]}
Vivian De Smedt
  • 1,019
  • 2
  • 16
  • 26
1

n2 is a reference to the list object in your dict. When you access ddic['c'], you are pointing to the same list object in the dict, not a copy of it.

Artur Gaspar
  • 4,407
  • 1
  • 26
  • 28
  • Strictly speaking, the list is neither "in" the dict nor "in" n2. Both the dict and the variable n2 hold a reference to it. – Artur Gaspar Mar 31 '15 at 19:05