2
my_list = [0] * 3
my_list[0] = 1

outputs to [1, 0, 0]

my_2ndlist = [[0] * 3] * 3
my_2ndlist[1][1] = 5

outputs to [[0, 5, 0], [0, 5, 0], [0, 5, 0]]

I think I know that x = 1 y = 1 makes x and y point to the same location in memory. So I get the sense of the second output, even if it's not what I think you would expect. But then I don't fully get the first as I would expect it's still 3 times a reference to the same memory location.

Any explanation that could help me understand better? Thank you.

Maurizio
  • 37
  • 5

1 Answers1

0

When you print addresses of my_list[0], my_list[1], my_2ndlist[0], my_2ndlist[1] you will see that my_list[0], my_list[1] have 2 different addreses and my_2ndlist[0], my_2ndlist[1] have same addresses.

my_list = [0] * 3
my_list[0] = 1
print(my_list)
print(id(my_list[0]), id(my_list[1]))

my_2ndlist = [[0] * 3] * 3
my_2ndlist[1][1] = 5
print(my_2ndlist)
print(id(my_2ndlist[0]), id(my_2ndlist[1]))

That happens because [0] * 3 will copy an integer object with the value zero 3 times. And in python when primitive type objects are copied they are deeply copied(integer is primitive type). But, [[0] * 3] * 3 this will copy list [0, 0, 0] 3 times. Lists are not primitive type objects so they are shallow copied. Maybe this link will help you to understand.

DimitrijeCiric
  • 446
  • 1
  • 10
  • 1
    thank you. at first glance, I would expect the [0] in the expression [0] * 3 to be an integer value "encapsulated" in a list, let's call it "x-list", and the expression result in x-list + x-list + x-list, therefore being treated as a list object. but I get the sense – Maurizio May 14 '22 at 15:07