assigning value in python dict (copy vs reference)

You’re wrestling with 2 different things here. The first is the idea of mutability vs. immutability. In python, str, int, tuple are some of the builtin immutable types compared to list, dict (and others) which are mutable types. immutable objects are ones which cannot be changed once they are created. So, in your example:

a = b = c = 1

After that line, all a, b and c refer to the same integer in memory (you can check by printing their respecitve id‘s and noting that they are the same). However, when you do:

a += 1

a now refers to a new (different) integer at a different memory location. Note that as a convention, += should return a new instance of something if the type is immutable. If the type is mutable, it should change the object in place and return it. I explain some of the more gory detail in this answer.


For the second part, you’re trying to figure out how python’s identifiers work. The way that I think of it is this… when you write a statement:

name = something

The right hand side is evaluated into some object (an integer, string, …). That object is then given the name on the left hand side1. When a name is on the right hand side, the corresponding object is automatically “looked up” and substituted for the name in the calculation. Note that in this framework, assignment doesn’t care if anything had that name before — it simply overwrites the old value with the new one. Objects which were previously constructed using that name don’t see any changes — either. They’ve already been created — keeping references to the objects themselves, not the names. So:

a = "foo"  # `a` is the name of the string "foo" 
b = {"bar": a}  # evaluate the new dictionary and name it `b`.  `a` is looked up and returns "foo" in this calculation
a = "bar"  # give the object "bar" the name `a` irrespecitve of what previously had that name

1I’m glossing over a few details here for simplicity — e.g. what happens when you assign to a list element: lst[idx] = some_value * some_other_value.

Leave a Comment