Understanding Python assignment
Here’s a quick question I often ask students in my Python classes:
>>> x = 100 >>> y = x >>> x = 200
After executing the above code, what is the value of y?
Many of my students, especially those with a background in C, are surprised. Didn’t we say that “y = x”? Thus, shouldn’t a change in x be reflected by a similar change in y?
Obviously not. But why is this the case?
Assignment in Python means one thing, and one thing only: The variable named on the left should now refer to the value on the right.
In other words, when I said:
y = x
Python doesn’t read this as, “y should now refer to the variable x.” Rather, it read it as, “y should now refer to whatever value x refers to.”
Because x refers to the integer 100, y now refers to the integer 100. After these two assignments (“x = 100” and “y = x”), there are now two references to the integer 100 that didn’t previously exist.
When we say that “x = 200”, we’re removing one of those references, such that x no longer refers to 100. Instead, x will now refer to the integer 200.
But y’s reference remains in place to where it was originally pointing, to 100. And indeed, the only way to change what y is referring to is via … assignment.
Think of this as assignment inertia: Without a new and explicit assignment, a variable will continue to refer to whatever it referred to previously.
Thus, while Python does have references (i.e., variables pointing to objects), it doesn’t have pointers (i.e., variables pointing to other variables). That’s a big difference, and one that makes the language easier to understand. But references can still be a bit tricky and confusing, especially for newcomers to the language.
Remember also that in an assignment, the right side is evaluated before the left side. By the time the left-hand-side is being assigned, any variables on the right-hand-side are long gone, replaced by the final value of the expression. For example:
>>> a = 10 >>> b = 20 >>> c = 30 >>> d = a + b * c
When we assign a value to the variable “d” above, it’s only after Python has evaluated “a + b * c”. The variables are replaced by the values to which they refer, the operations are evaluated, and the final result (610) is then assigned to “d”. “d” has no idea that it was ever getting a value from “a”, “b”, or “c”.