-2

I have this piece of code:

a = 2
b = a
a = 3
print(b)

Given this, I expected the value of a would turn out to be 3. However, when I execute the code the following is returned:

2

My question is, why doesn't it print 3?. Do variables don't get updated in situations like this one?.

Jonathan Hall
  • 75,165
  • 16
  • 143
  • 189
Jotate
  • 1
  • 3
    An assignment doesn't make the two variables equivalent, it just copies the value from one to the other. – Barmar Jul 30 '21 at 20:08
  • 1
    For immutable values such as integers and strings, the assignment b=a makes b refreence the value of a at that tome, i.e. 2 – DisappointedByUnaccountableMod Jul 30 '21 at 20:09
  • 2
    It prints `2` because `b` is `2`. Variables don't get updated if you reassign a different variable. Mandatory link to [Ned Batchelder](https://nedbatchelder.com/text/names.html) – quamrana Jul 30 '21 at 20:09
  • 3
    @balmy This has nothing to do with mutability. The same thing happens with mutable values. – Barmar Jul 30 '21 at 20:09
  • 1
    https://stackoverflow.com/questions/8056130/immutable-vs-mutable-types – pyeR_biz Jul 30 '21 at 20:09
  • 1
    @balmy `a = [1]; b = a; a = [2]; print(b)` – Barmar Jul 30 '21 at 20:10
  • 4
    You should think of assignment statements as attaching a nametag to an object, nothing more.. see here https://stackoverflow.com/a/42908412/674039 – wim Jul 30 '21 at 20:10
  • @wim The thing with the nametag is the one explanation most new Python developers understand. – Matthias Jul 30 '21 at 20:11
  • If assignment worked the way you suggest, reassigning `a` from 2 to 3 would make 2 equal to 3. – khelwood Jul 30 '21 at 20:25
  • 2
    @Barmar Please don't use the word "copy" in any explanation of how assignment works in Python :) – chepner Jul 30 '21 at 20:40
  • 1
    Required reading: https://nedbatchelder.com/text/names.html – chepner Jul 30 '21 at 20:40
  • 1
    @Barmar *it does not copy* – juanpa.arrivillaga Jul 30 '21 at 21:07
  • @balmy **mutable or immutable is irrelevant**. Assignment has the *exact same semantics for both types** – juanpa.arrivillaga Jul 30 '21 at 21:07
  • @juanpa.arrivillaga What it copies is a reference to the object, it doesn't duplicate the object. But I don't want to get into an argument about the ambiguity of the word "copy". I'm not sure what other verb to use ("transfer"?). – Barmar Jul 30 '21 at 21:10
  • @Barmar I mean, that is an implementation detail that distracts from the core semantics, IMO and you did say "copies the value".. In any case, I just say "assignment creates a reference to the same object". – juanpa.arrivillaga Jul 30 '21 at 21:15
  • @juanpa.arrivillaga That's what the OP thought, except he thinks that the reference is between the variables themselves. – Barmar Jul 30 '21 at 21:17
  • @Barmar a *distinct* reference, perhaps? – juanpa.arrivillaga Jul 30 '21 at 21:17
  • @juanpa.arrivillaga It's a difficult concept to encapsulate in a verb, especially when the audience doesn't really understand what's going on. – Barmar Jul 30 '21 at 21:18

2 Answers2

3

You need to learn to separate the notion of an "object" from a "name". Your first statement creates an integer object, and binds it to the name a. Your second statement binds that same object to the name b. Your third statement creates a NEW integer object with the value 3 and binds it to the name a. The name b is still bound to the old object.

The assignment operator always creates a new object binding. Compare this to modifying a list in place:

a = [1,2]
b = a
a[0] = 3
print(b)

produces [3,2], because we haven't changed the bindings. We have modified the single list object that both names are bound to.

I actually wrote an article about this, since it is such a key concept: https://github.com/timrprobocom/documents/blob/main/UnderstandingPythonObjects.md

Tim Roberts
  • 48,973
  • 4
  • 21
  • 30
  • Actually in CPython these small integer objects have already been created at interpreter startup, but this is basically right. – wim Jul 30 '21 at 20:14
1

It works like expected.

  1. a = 2 --> variable a saves the value 2.

  2. b = a --> variable b saves the value of variable a (which is 2).

  3. a = 3 --> variable a saves the value 3.

If you change something inside of an object, it changes for all variables that reference this object (because they all reference the same place where it is stored). But assigning a new object (in this case a numeral value) to a variable does not change any other variables.

=> b still references 2

Cactusroot
  • 1,019
  • 3
  • 16