tags:

views:

103

answers:

5

Why is it that when I do the following:

x = y = {}

Everytime I modify, x like x[1] = 5, I also end up modifying y and vice versa?

+7  A: 

You assign the names x and y to be pointing to one and the same dictionary, what behaviour would you expect?

If you want them to point to different dictionaries, use

x = {}
y = {}

or

x,y = {},{}
ChristopheD
That looks more like a question, not an answer.
Agos
@Agos: Sometimes, a rhetorical question is an adequate answer.
Tomalak
+1  A: 

That is how references works. With x = y = {}, there are two reference variables, but they're both pointing to the same object. With x[1] = 5, you're not really modifying x itself, but rather, the object referred to by x. This is the same object referred to by y, unless you set x and/or y to refer to new objects.

See also

polygenelubricants
+2  A: 

Because x and y references the same dictionary.

What happens under the hood:

-----   ------- 
| x | = | ref |----- 
-----   -------    |
                   v
                 ------
                 | {} |
                 ------
                   ^
-----   -------    |
| y | = | ref |-----
-----   ------- 

Read about mutable and immutable data:

petraszd
A: 

As the other answers say, the original gotcha happens because you're assigning a reference. The next level of confusion is when you do something like this:

a = [[1]]
b = a[:] # You might think [:] will protect you from the original gotcha.
a[0][0] = 2
print b[0][0] # It's 2...why did this change?

It changed because the a[:] slice is actually copying a reference to a[0]. In other words, even though a and b refer to different lists because you used [:], the first element in each is referring to the same list. It's the original problem in a new form. The correct approach here is to do

import copy
a = [[1]]
b = copy.deepcopy(a)
a[0][0] = 2
print b[0][0] # 1
+1  A: 

Variables on Python don't work like "boxes" (where you put objects), but as "labels" (where you assign names to objects).

So when you do:

x = y = {}

You are really saying to Python:

I want to call {} as x and y.

Another way to understand this is that the {} syntax is just a shortcut for dict(), which simply returns a new Dict object. So another way to see would be:

x = y = dict()

This returns just one dict object, and assigns two names to it (x and y).

hcalves