Understanding Python assignment

June 18, 2019 . By Reuven

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?

The answer:

>>> print(y)
100

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

Related Posts

Prepare yourself for a better career, with my new Python learning memberships

Prepare yourself for a better career, with my new Python learning memberships

I’m banned for life from advertising on Meta. Because I teach Python.

I’m banned for life from advertising on Meta. Because I teach Python.

Sharpen your Pandas skills with “Bamboo Weekly”

Sharpen your Pandas skills with “Bamboo Weekly”
  • SakuraWulf says:

    “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. 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.”” So, you’re confusing your students, essentially. The variable on the left doesn’t refer to the value on the right; it refers to what the value on the right refers to.

    • No, it refers to the value on the right. If there is a reference (e.g., a variable) rather than a value, then it refers to the value that is being referenced.

      If it’s a value (e.g., “x = 5”) then it refers to the value that you see. If it’s a variable (e.g., “x = y”) then it refers to the value that the variable on the right refers to.

  • I think it is the other way around. In C/C++ assignment basically copies the value. In fact, this is what confuses me:
    >>> x = [100]
    >>> y = x
    >>> x.append(200)
    >>> y
    [100, 200]

  • Furthermore, Python objects work exactly the way your students apparently think integers work in C:

    >>> class Something(object):
    … pass

    >>> x = Something()
    >>> y = Something()
    >>> x.value = 100
    >>> y = x
    >>> x.value = 200
    >>> print(y.value)
    200
    >>>

    I think I’m missing the point?

    • I don’t have a good answer, except that this question routinely trips them up and surprises them.

      • Winfried Wilcke says:

        I’m totally new to Python and very confused with assignments. This snippet below produces totally unexpected result:

        #b1 and q1 are (numpy) one-dimensional arrays, b1 was #previously filled with random integers, either 0 or 1

        q1=b1
        #printing out b1 now shows that b1[2]=0

        if (b1[2] == 0):
        q1[2]=22
        # now printing q1 and b1 shows that b1[2] has now ALSO changed from 0 to 22 !! How is this possible?!

        help greatly appreciated, I have been chewing on this for hours now.. Winfried

        • In python, as it’s said above “y=x” tells that x and y are now pointing at the same piece of data in memory. And while new assignment to either x or y, removes this connection, other commands, like append, assigning to an element of x, etc do not change fact that x and y are referring to same data. So changing either of them this way will change other one too

  • What kind of C has your students learned?

    $ cat test.c
    #include

    int main(void) {
    int x, y;
    x = 100;
    y = x;
    x = 200;
    printf(“%dn”, y);
    }
    $ gcc -Wall -o test test.c
    $ ./test
    100
    $

    • I must admit, maybe that I was just using the opportunity to make a swipe at C… my students tend to come from a C, C++, C#, and Java background, and my experience with those languages is far, far from fluent. So I figured that the confusion was the result of their C backgrounds. Maybe they’re just confused? I dunno!

      • If you start by saying “in Python everything is objects”, then they might be thinking “I’ve learned that objects are assigned by reference”, and thus reach the wrong answer? Hard to tell!

  • {"email":"Email address invalid","url":"Website address invalid","required":"Required field missing"}
    >