0

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?

1
  • Hint: You expect "assignment by value", but what actually happens is "assignment by reference". Commented Jul 12, 2010 at 21:25

5 Answers 5

6

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 = {},{}
Sign up to request clarification or add additional context in comments.

1 Comment

@Agos: Sometimes, a rhetorical question is an adequate answer.
2

Because x and y references the same dictionary.

What happens under the hood:

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

Read about mutable and immutable data:

Comments

1

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

Comments

1

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

Comments

0

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

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.