0

I've run into a strange inconsistency. This is a simplified version of the problem:

func1={
    'flist':[12,13,14],
    'fnum':10
}

dlist=func1['flist']
dnum=func1['fnum']

dlist+=[16]
dnum+=1

print(func1)
print(dnum)

The output is:

{'flist': [12, 13, 14, 16], 'fnum': 10}

11

Why is that the changes to the variable dlist are carried over to flist in func1, but changes in dnum are not carried over to fnum in func1?

flist has changed, fnum has not.

jonrsharpe
  • 115,751
  • 26
  • 228
  • 437
  • 4
    Lists are mutable, integers are not. `+=` on a list is like calling `.extend`, see https://stackoverflow.com/q/2347265/3001761. – jonrsharpe Feb 07 '22 at 23:19

1 Answers1

1

This has to do with the mutability of the underlying objects. Since func1['flist'] refers to a list, when you do dlist=func1['flist'] you are actually getting a reference to the memory address of func1['flist'] and then when you add another value, you are modifying the same object in memory. This is because lists are mutable objects and referred to by reference.

On the other hand when you do dnum+=1, what is happening in memory is that 10+1=11 is being created as a new object in memory and then dnum is set to point to the new memory address. This has no effect on the memory address and therefore the value of func1['fnum']. This is the behaviour that happens for immutable types.

fhorrobin
  • 362
  • 1
  • 10
  • 3
    _"you are getting the value itself, not a reference"_ - that's not true, you get a reference to an object in both cases. – jonrsharpe Feb 07 '22 at 23:25
  • Yeah my bad, I did a poor job explaining that. I have tried to adjust my answer to better explain it. – fhorrobin Feb 07 '22 at 23:29