1

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.

Mark Rotteveel
  • 100,966
  • 191
  • 140
  • 197
BertHobe
  • 217
  • 1
  • 14
  • 2
    Variables store only references (technically pointers) to objects. Assigning one variable to another only copies the reference/pointer. This is not specifically related to dicts or lists. – Michael Butscher Sep 08 '21 at 16:02
  • Everything that is true about lists in this post will apply to other objects as well https://stackoverflow.com/questions/2612802/list-changes-unexpectedly-after-assignment-why-is-this-and-how-can-i-prevent-it – Matthew Barlowe Sep 08 '21 at 16:03
  • 3
    @Randy That's different because you're assigning the variable, not modifying what the variable refers to. You get the same effect with mutable types: `a = [1]; b = a; b = [2]` leaves `a = [1]` – Barmar Sep 08 '21 at 16:07

3 Answers3

1

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.

Lecdi
  • 2,189
  • 2
  • 6
  • 20
0

When you're deleting a variable like del d1. You delete the variables that points towards the dict object d1 was pointing too.

However, d2 = d1 means we assign to the variable d2 the pointer the object d1 was pointing.

Therefore when d1 is deleted, d2 still points towards {'Andy': 1, 'Jane': 2, 'Mary': 3, 'John': 4}

0

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

Python has names (or pointers to the memory), not variables. Dictionaries behave not like lists but like other mutable objects (list, set, dict). To avoid this (and create a new object) use list2 = list.copy()

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

Yes, You can`t change tuple directly but you can do it through the list:

x = ("item1", "item2", "item3") 
y = list(x) 
y[1] = "item4" 
x = tuple(y)

And similar to lists when you try to create tuples you will get same Ids for 2 different names

tuple1 = (1, 2, 3) 
tuple2 = tuple1

print(id(tuple1)) 
print(id(tuple2))

2458684853128

2458684853128

This occurs because compilers are smart. The CPython compiler attempts to make optimizations called peephole optimizations, which help save execution steps whenever possible.

Tim Uzlov
  • 181
  • 2
  • 6