8

I just discovered in the definition of variables in Python. Namely:

a = b = 0
a = 1

gives me a=1 and b=0 or a and b are two independent variables.

But:

a = b = []
a.append(0)

gives me a = [0] and b = [0], or a and b are two references to the same object. This is confusing to me, how are these two cases different? Is it because int are primitive types or because lists are just pointers?

Learning is a mess
  • 7,479
  • 7
  • 35
  • 71
  • 1
    the 2 operation are different. In first case you assign a new value to a, while on second modify the object pointed by a... – Arthur Vaïsse Apr 23 '15 at 14:04
  • 4
    The tests are not consistent. Try `a = b = []; a = [1, 2, 3]` – thefourtheye Apr 23 '15 at 14:05
  • 1
    Relevant video: [Facts and Myths about Python names and values](https://www.youtube.com/watch?v=_AEJHKGk9ns) – Zero Piraeus Apr 23 '15 at 14:09
  • 6
    Downvoters: this is a perfectly reasonable question, and something that trips a lot of Python programmers up. – Zero Piraeus Apr 23 '15 at 14:12
  • 3
    And in text form: [Facts and myths about Python names and values](http://nedbatchelder.com/text/names.html) – PM 2Ring Apr 23 '15 at 14:19
  • See a popular answer of mine [here](http://stackoverflow.com/questions/29810632/different-ways-of-deleting-lists/29810816#29810816). – Malik Brahimi Apr 23 '15 at 14:21
  • 1
    Also try `a=b=[];a+=[1];a;b;a=a+[2];a;b`. The difference is that `a+=` mutates the original object, `a=a+` creates a new object and binds that to the name `a`. – PM 2Ring Apr 23 '15 at 14:41

2 Answers2

13

a and b point to the same object always. But you cannot alter the integer, it is immutable.

In your first example, you rebound a to point to another object. You did not do that in the other example, you never assigned another object to a.

Instead, you asked the object a references to alter itself, to add another entry to that object. All other references to that same object (the list), will see these changes. That's because list objects are mutable.

A proper comparison would be to re-assign a to point to a new list object:

a = b = []
a = [0]

Now you rebound a and b is still referencing the first list object.

Martijn Pieters
  • 1,048,767
  • 296
  • 4,058
  • 3,343
1

You must understand that a and b are simply references that point to an initially empty list:

>>> a = [] # set variable a to an empty list
>>> b = a  # sets b to what a is pointing to
>>> a.append(0) # add a zero to the original

# Step 1: A --> [ ]
# Step 2: A --> [ ] <-- B
# Step 3: A --> [0] <-- B
Malik Brahimi
  • 16,341
  • 7
  • 39
  • 70