Dictionaries point like lists? Troubles to understand logic behind ‘pointing’

I am aware of the fact that in python lists behave as follows:

l1=[1,2]
l2=l1
l2[0]=4

print(l1)

So the output is [4, 2], not [1,2], as one could assume.

When I do this with dictionaries the effect is the same.

So the following code:

d1={'Andy':1, 'Jane':2, 'Mary':3}
d2=d1
d1['John']=4
del d1
print(d2)

gives {'Andy': 1, 'Jane': 2, 'Mary': 3, 'John': 4} as an output. However with dictionaries I did not expect this. I thought d2 would be {'Andy': 1, 'Jane': 2, 'Mary': 3}. (I now there is an extra .copy() function which I could use to make sure d2 is a real copy, but I did not know I have to use it if I want to copy it.) Also when I trace it with id() I can see that the id for d2 and d1 (if not deleted) is the same. So as in the case of lists.

From which fact does it arise that dictionaries have a “point” behaviour like lists or where is it written that dictionaries behave like this?

With tuples it is the same, however as tuples are immutable the problem is not that obvious there.

Answer

All variables you create in your code “point” to some data stored in memory, the only difference is whether a variable is mutable or immutable. Like you said, tuples are immutable so when you change a tuple you are effectively creating a new variable with the same name. This means if you run the following code:

a = (1, 2)
b = a
a += (3, 4)
print(b)

You will get (1, 2) as an output because line 3 creates a new variable with the name a and does not affect b. However, because lists and dictionaries are both mutable, changing one can change the actual data that both variables point to so both variables are affected.