Can you explain this behavior using Python defaultdict and autovivitation

I'm not sure if I'm missing something trivially obvious here, but I can't for the rest of my life understand how the code below manipulates to give the result it does.

import collections

tree = collections.defaultdict(dict)
tree[0][1] = tree[1]
print tree
tree[1][2] = tree[2]
print tree

      

And here's the magic conclusion:

defaultdict(<type 'dict'>, {0: {1: {}}, 1: {}})
defaultdict(<type 'dict'>, {0: {1: {2: {}}}, 1: {2: {}}, 2: {}})

      

The first line of the output makes sense. Then we will consider the purpose tree[1][2] = tree[2]

and its subsequent conclusion.

I understand that the record 2: {}

was created by evaluating the RHS expression tree[2]

.

I also understand that a record 1: {2: {}}

is created by evaluating the LHS expression tree[1][2]

and assigning it to the RHS value.

What I don't understand is how the dictionary entry 0: {1: {}}

was updated before 0: {1: {2: {}}}

when there was no reference to tree[0]

.

+3


source to share


2 answers


Because when you execute tree[0][1] = tree[1]

, tree[0][1]

refers to the same object as tree[1]

, so if any changes happen internally tree[1]

, it will be reflected to tree[0][1]

.

And when you do tree[1][2]

, you are actually making changes internally tree[1]

, rather than creating a tree[1]

reference to a new object.

Example, after your changes try to do this -



>>> tree[1]['blah'] = 'Hello'
>>> print(tree)
defaultdict(<class 'dict'>, {0: {1: {2: {}, 'blah': 'Hello'}}, 1: {2: {}, 'blah': 'Hello'}, 2: {}})

      

Only if you do something like - tree[1] = <somethingelse>

, you make the link a tree[1]

reference to the new object, in which case it won't appear in tree[0][1]

.

+4


source


Many objects (not primitives) are stored as references, not values. So if you assigned a to b then change a, b also change.



0


source







All Articles