Search code examples
pythonvariablesmemoryimmutabilitymutable

Variable assignment and modification with regards to memory addresses


Suppose I assign two variables to integers:

a = 1
b = 2

Now, I'll assign a to b:

a = b

As expected, a == 2, because a has been set to the memory address of b.

But actually, it hasn't. If I do

b += 1

a still equals 2. Why does a not point to b?


Solution

  • The behavior in the example is as follows

    In [1]: a = 1                                                                                                                                                                     
    
    In [2]: b = 2                                                                                                                                                                     
    
    In [3]: a = b                                                                                                                                                                     
    
    In [4]: b+=1                                                                                                                                                                      
    
    In [5]: b                                                                                                                                                                         
    Out[5]: 3
    
    In [6]: a                                                                                                                                                                         
    Out[6]: 2
    

    In the example, when you do a=b, both a and b are pointing to the same reference, but when you b += 1, the operation of adding 1 to b, creates a new integer value 3 for b and b points to that value, but a is still pointing to the old value 2

    Note that trying to do it with mutable types like a list works as what you were excepting would happen to an integer

    In [1]: a = [1]                                                                                                                                                                   
    
    In [2]: b = [2]                                                                                                                                                                   
    
    In [3]: a = b                                                                                                                                                                     
    
    In [4]: b.append(2)                                                                                                                                                               
    
    In [5]: a                                                                                                                                                                         
    Out[5]: [2, 2]
    
    In [6]: b                                                                                                                                                                         
    Out[6]: [2, 2]
    
    In [7]: b += [3, 4];                                                                                                                                                                        
    
    In [8]: b
    Out[8]: [2, 2, 3, 4]
    
    In [9]: a
    Out[9]: [2, 2, 3, 4]
    
    

    Now what happened here? We changed b but a changed as well, this is because the append or update of the list happens in-place and since a was pointing to b both ends up getting updated!

    What happens for += operator is defined by __iadd__ method of a class. For int-s all the __iXXX__ methods return a new instance of int. For list-s __iadd__(self, other) does self.extend(other); return self, so variable keeps pointing to same object.

    As a result, even integers can be made to behave as a list, an example is here courtesy @imposeren